perm filename BOOT10.MAC[SS,SYS]1 blob
sn#729213 filedate 1983-11-11 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00070 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00012 00002 TITLE BOOT - A NEW VERSION OF THE LEVEL D DISK BOOTSTRAP BOOVER BOOMIN BOOEDT BOOTVA
C00016 00003 SUBTTL REVISION HISTORY
C00019 00004 SUBTTL CODING CONVENTIONS/CONSIDERATIONS
C00024 00005 SUBTTL PARAMETER DEFINITIONS .CHBEL .CHCNH .CHTAB .CHLFD .CHVTB .CHFFD .CHCRT .CHCNU .CHCNZ .CHESC .CHDEL FL.RUB FL.OVW FL.WLD FL.RIB FL.EXR FL.ZER FL.IO FL.LDE FL.FFL FR.DEV FR.FIL FR.EXT FR.PTH FR.RBT FR.DMP FR.LOD FR.STA FR.1ST FR.ALL FX.CLR
C00029 00006 MONITOR PARAMETERS WHICH MUST AGREE WITH COMMON/COMMOD. HOMNAM HOMSNM HOMLUN HOMBSC HOMSCU HOMCNP HOMCLP HOMBPC HOMREF HOMMFD HOMCOD CODHOM HOMSLF RIBFIR RIBPPN RIBNAM RIBEXT RIBSIZ RIBSTS RIPDMP RIBXRA RIPNUB RIBCOD CODRIB RIBSLF BOOTSA BOOTWD LBNHOM LB2HOM LBOBAT LIMLVL MBTCOM MAXPGS .EPHSB
C00033 00007 MISCELANEOUS HARDWARE PARAMETERS IT.DON IT.BSY APRRST CLRAPR PDLLEN LINBFL BLKSIZ PAGSIZ MAXUNI P2BLSH B2WLSH W2BLSH P2WLSH W2PLSH .VBOOT .VPAG0 .VMOVE .VZERO .MBOOT .MPAG0 .MMOVE .MZERO
C00038 00008 IFN FTKL10!FTKI10,< CI.XDN CI.122 CI.1ER CI.1RA CI.2ER CI.2RA CO.XDN CO.XSX CO.XMI CO.1RB CO.1AE CO.2RB CO.2ME DO.XCR DO.XSR DI.XCE DI.XSM DI.XSB DO.XDS DO.XDT DO.XDC DO.1CR DO.2ST DO.XCL DO.XRP DO.XRD DO.XWT RH2TRA RH2JMP R2IOWL R2BCNT R2WCNT R1BCNT R1WCNT
C00044 00009 IFN FTKS10,< SO.UPR SO.VFT SO.RBT SO.USR SO.UBI SI.UER SO.CS1 SI.RDY SI.S1E SO.WC SO.BA SO.DA SO.CS2 SO.DS SO.DSM SO.DSB SI.DT SI.DSK SO.DC SO.DCL SO.RIP SO.WRT SO.RED RSBCNT
C00047 00010 SUBTTL MACRO DEFINITIONS OFFSET OFFSET LABEL BTSLOC
C00050 00011 MACROS TO HELP IN INSERTING ENTRIES INTO THE PAGE MAP ZZ ZZ
C00053 00012 SUBTTL DATA AREAS .RDATA BTSLOC EPTABS R2IOWD BTSLOC
C00058 00013 BLK(HOM,BLKSIZ) HOM BLOCK FOR CURRENT UNIT SWTVLV SWTVLL FILSPE NXMTBE
C00063 00014 HERE AFTER BEING LOADED INTO MEMORY. WE ARE (PROBABLY) RUNNING BOOT
C00069 00015 HERE WHEN THE .VBOOT ADDRESS SPACE HAS BEEN MAPPED TO DO SOME ONCE MAPPED
C00073 00016 ROUTINE TO PROMPT THE USER AND DUMP/LOAD/RELOAD THE MONITOR. CALL RLDMON RLDMO1 RLDMO2
C00078 00017 CHGEBR: CHGEBR CHGUBR VERMSG
C00081 00018 SUBTTL DUMP MONITOR ASKSTR DODUMP DODUM1 DODUM2 DODUM3 DODUM4
C00086 00019 HERE IF AN ERROR IS DETECTED IN THE DUMP OR LOAD. USE THE ERROR LODERR DMPERR DMPER1 DMPER2 DMPER3
C00091 00020 TABLE OF ERROR MESSAGES INDEXED BY THE ERROR CODE RETURNED IN T1. EMSTAB FNFOFS EMSTBL DMPDSP DMPDSL LODDSP LODDSL STRFUL
C00096 00021 ROUTINE TO DUMP THE MONITOR ONTO THE CRASH FILE SPECIFIED IN THE DUMP DUMP1 DUMP2
C00102 00022 DUMP3: MOVE T1,[SV.END,,1] GET END OF DESCRIPTOR MARKER DUMP3 DUMP4 DUMP5 DUMP6
C00107 00023 SUBTTL RELOAD MONITOR DOLOAD DOLOA1 DOLOA2 DOLOA3
C00111 00024 ROUTINE TO LOAD A NEW MONITOR INTO CORE. CALL WITH THE FILESPEC AREA LOAD LOAD1 LOAD2 LOAD3 LOAD4 LOAD5 LOAD6 LOAD7
C00117 00025 SUBTTL FILE SEARCH SUBROUTINES FNDMON
C00121 00026 ROUTINE TO FIND A FILE AND SETUP ITS RIB IN RIB. CALL WITH FNDFIL FNDFI1 FNDFI2
C00125 00027 ROUTINE TO FIND THE MFD FOR A STRUCTURE. CALL WITH DEV CONTAINING FNDMFD FNDMF1 SRCHFD SRCHF1 SRCHF2
C00130 00028 SUBTTL BLOCK READ/WRITE SUBROUTINES WRTRIB WRTBUF REDBUF
C00134 00029 ROUTINE TO POSITION AN EXE FILE SO THAT THE NEXT READ WILL READ POSFIL REDBLK
C00139 00030 ROUTINE TO FIND A UNIT AND READ IT'S HOM BLOCK. CALL WITH LUNPOS FNDLUN FNDUNI FNDUN1 FNDUN2 FNDUN3
C00144 00031 ROUTINE TO READ A HOM BLOCK. REDHOM REDHO1 REDHO2
C00148 00032 ROUTINE TO READ A RIB. REDRIB REDRBP
C00153 00033 ROUTINE TO SETUP A TRANSFER TO/FROM DISK. SELBLK SELBL1 SELBL2 SELBL3
C00156 00034 SELBL4: MOVN M,T1 GET -VE NUMBER OF BLOCKS IN REQUEST SELBL4 SELBL5 SELBL6
C00161 00035 SUBTTL SUPPORT SUBROUTINES CLRBUF SETIOT ERRTAB SNTERR FNTERR UPDERR EOFERR IOFERR BDFERR MCCERR NSSERR ERRTBL ALLERR
C00165 00036 ROUTINE TO READ DATA INTO A VIRTUAL ADDRESS. VRTRED VRTWRT MAPADR
C00170 00037 ROUTINE TO SAVE P1 AND P2 AND CALL THE CALLER AS A COROUTINE SAVE2 SAVFR
C00174 00038 SUBTTL MOVE BOOT TO TOP OF MEMORY AND ZERO CORE MOVBTS
C00179 00039 HERE AFTER HAVING MOVED BOOT TO THE TOP OF CORE TO ZERO ALL OTHER MOVBT1 MOVBT2
C00183 00040 SUBTTL NXMTAB HANDLING ROUTINES FINDHI FINDH1 FINDH2 FNDPGS FNDPG1 FNDPG2
C00188 00041 ROUTINE TO CHECK NXMTAB TO SEE IF A PAGE EXISTS. CHKNXM SUNXMT SUNXM1 SUNXM2
C00193 00042 ROUTINE TO DETERMINE IF A PAGE EXISTS IN MEMORY BY TOUCHING REFMEM REFTRP
C00197 00043 SUBTTL TRAP HANDLING TRAP PFTRAP PFTRA1
C00201 00044 ROUTINE TO PRINT THE CONI APR AND RDERA (IF A KL10). PRTAPR
C00204 00045 SUBTTL COMMAND PARSING PARSE PARSE1 PARSE2 PARSE3 CMDERR TRMTAB TRMTBL
C00208 00046 HERE TO PROCESS DEVICE IN COMMAND STRING CMDDEV CMDFIL CMDPTH CMDPT1 CMDPT2
C00213 00047 HERE TO PROCESS THE END OF THE COMMAND LINE CMDEOL
C00216 00048 HERE TO PROCESS A SWITCH IN THE COMMAND STRING CMDSWT CMDSW1 CMDSW2 SWTTAB SWTTBL
C00220 00049 SUBTTL COMMAND INPUT STOFIL GETSIX GETSI1 GETSI2 GETOCT GETOC1
C00225 00050 ROUTINE TO RETURN THE NEXT CHARACTER FROM THE COMMAND STREAM. GETCHR ASKYN CPOPJ1 CPOPJ
C00229 00051 ROUTINE TO PRINT A PROMPT STRING, AND READ A COMMAND LINE INTO REDLIN REDLI1 REDLI2 TPOPJ
C00233 00052 HERE TO PROCESS RUBOUTS REDRUB REDRU1 REDCNU REDCU1
C00237 00053 SUBTTL COMMAND OUTPUT PRRBCR PRCRLF PRBSL PRCOMA PRLBKT PRRBKT PRMSG PRMSG1 PRSIX
C00242 00054 ROUTINE TO PRINT AN OCTAL NUMBER ON THE CTY. PROCT PRHWD PRHWD1 PRHWD2 ECHO
C00245 00055 ROUTINE TO PRINT THE CURRENT FILESPEC FROM THE DATA BASE. PRFILE PRFIL1
C00249 00056 SUBTTL LOWEST LEVEL CTY INPUT/OUTPUT ROUTINES TYO DODTE
C00253 00057 ROUTINE TO READ ONE CHARACTER FROM THE CTY. TYI BRKTAB
C00257 00058 SUBTTL DISK SUPPORT SUBROUTINES REDREG DRVTYP DRVTY1
C00261 00059 TABLES DEFINING THE DRIVE TYPES OF THE DRIVES WE KNOW ABOUT AND DRTTAB DRTTBL BPCTAB BPTTAB
C00264 00060 SUBTTL BYTE POINTERS INTO DATA STRUCTURES DESRBU DENRBU DESRBA DENRBA DEYRBU DEYRBA
C00267 00061 SUBTTL TABLES DRIVING DEVICE DEPENDENT I/O DVCTAB DVCTBL IOTTAB DODATO DODATI DOCONI DOCONO DOCNSO IOTTBL
C00271 00062 THE FOLLOWING TABLES GIVE THE DISPATCH ADDRESSES FOR THE CONTROLLER OFS REDTAB WRTTAB
C00275 00063 IFN FTKL10!FTKI10,< R12WRT R12RED R12XFR R10XFR R12XF1
C00280 00064 ROUTINE TO SETUP THE CHANNEL COMMAND LIST FOR THIS TRANSFER AND R12SET R12SE1 R12SE2 R12SE3 R12SE4 R12SE5 R12SE6
C00286 00065 ROUTINE TO INITIALIZE THE RH10/RH20 FOR A TRANSFER. R12INI R12CHK
C00290 00066 ROUTINE TO WAIT FOR THE RH10/RH20 TO FINISH A TRANSFER. R12WAT R12CLR
C00294 00067 IFN FTKS10,< R11WRT R11RED R11XFR R11XF1
C00299 00068 ROUTINE TO SETUP THE UBA MAPPING REGISTERS, AND THE DRIVE REGISTERS R11SET R11SE1
C00304 00069 ROUTINE TO INITIALIZE THE RH11 FOR A TRANSFER. R11INI R11CLR
C00308 00070 $DEPHASE BOOLEN BOOPGS BOOEND
C00309 ENDMK
C⊗;
TITLE BOOT - A NEW VERSION OF THE LEVEL D DISK BOOTSTRAP ;⊗ BOOVER BOOMIN BOOEDT BOOTVA
SUBTTL G.M. UHLER/GMU 05 JUL 80
SEARCH F,S
IFN FTKL10,<
SEARCH DTEPRM
>
SALL
;COPYRIGHT (C) 1980 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
BOOVER==1 ;MAJOR VERSION NUMBER
BOOMIN==0 ;MINOR VERSION NUMBER
BOOEDT==4 ;EDIT NUMBER
;DEFINE THE SYMBOL FTPAGE TO BE THE FIRST PHYSICAL PAGE INTO WHICH
;BOOT IS TO BE LOADED. THEN LOC THE ASSEMBLY TO THAT POINT.
IFNDEF FTPAGE,<FTPAGE==773>
LOC <FTPAGE*1000> ;START ASSEMBLY AT THAT ADDRESS
BOOTVA: ;FIRST VIRTUAL ADDRESS IN BOOT
SUBTTL REVISION HISTORY ;⊗
COMMENT `
1 05-Feb-80 Add the /REBOOT switch and support for system sleep.
2 15-Jun-80 Change the default filename for /REBOOT from SYSTEM to
CRASH.
3 05-Jul-80 Change the definitions of APRRST and CLRAPR for the
KS10 to reflect empirical evidence (i.e. make it work)
4 05-Jul-80 After powerup, the KS10 wants a WREBR 0 before the
WREBR to set the EBR. I'm not sure why it's true or
why it works but it fixes the ?PAR ERR's.
`
SUBTTL CODING CONVENTIONS/CONSIDERATIONS ;⊗
;AC CONVENTIONS IN THIS PROGRAM:
;
; S - FLAGS (SEE FL.XXX, FR.XXX)
; J - INDEX INTO DEVICE CODE TABLE
; U - PHYSICAL UNIT NUMBER
; W - OFFSET INTO TYPE TABLE (RH10, RH20, RH11, ETC.)
; R - PHYSICAL OR VIRTUAL CORE ADDRESS OF START OF TRANSFER
; F - LOGICAL BLOCK ON UNIT OF FIRST BLOCK TO TRANSFER
; M - NUMBER OF BLOCKS TO TRANSFER
; T1-T4 - TEMPORARIES. NOT GUARENTEED ACROSS SUBROUTINE CALLS EXCEPT
; WHERE EXPLICITLY NOTED.
; P1,P2 - PRESERVED REGISTERS (ACROSS SUBROUTINE CALLS)
; P3,P4 - FILENAME, EXTENSION OF FILE BEING SEARCHED FOR. MAY
; NOT BE PRESERVED ACROSS ALL SUBROUTINE CALLS
;
;
;THIS PROGRAM IS CONSTRUCTED IN TWO PARTS. THE FIRST STARTS AT THE
;LABEL BOOT WHERE WE START EXECUTION UNPAGED AS WE ARE LOADED INTO
;MEMORY. THE FIRST THING THAT WE DO IS TURN ON PAGING, MAPPING THE
;LOW 256K OF MEMORY 1 FOR 1. THE 1 FOR 1 MAP IS ASSEMBLED IN SO THE
;WE DON'T HAVE TO BUILD IT AT RUN TIME. WE THEN CHANGE THE EPT
;TO MAP PHYSICAL MEMORY INTO THE .VBOOT VIRTUAL ADDRESS SPACE AND
;THEN JUMP INTO IT.
;
;THE SECOND, AND MOST SUBSTANTIAL, PART OF BOOT RUNS IN THE .VBOOT
;VIRTUAL ADDRESS STARTING AT THE VIRTUAL ADDRESS SPECIFIED BY THE
;VALUE OF THE SYMBOL .VBOOT. THE .VBOOT ADDRESS SPACE IS NOT
;ADDRESSABLE UNTIL THE LABEL MAPPED AND ALL REFERENCES TO THE
;DATA LOCATIONS BEFORE THAT LABEL MUST BE OFFSET BY A "-.RDATA"
;TO MAKE THEM PHYSICAL/1 FOR 1 VIRTUAL ADDRESSES. WHEN BOOT HAS
;TO MOVE ITSELF ELSEWHERE IN MEMORY, IT SIMPLY MAKES THE DESTINATION
;ADDRESSABLE, BLTS ITSELF, AND CHANGES THE MAPPING OF THE .VBOOT
;ADDRESS SPACE TO MAP THE NEW PHYSICAL MEMORY. ALL THIS MEANS THAT
;MOST OF THE PROGRAM REALLY DOESN'T CARE WHERE IT IS IN MEMORY.
;WE JUST MAP IT APPROPRIATELY AND IT RUNS IN ITS OWN, UNCHANGING,
;VIRTUAL ADDRESS SPACE.
SUBTTL PARAMETER DEFINITIONS ;⊗ .CHBEL .CHCNH .CHTAB .CHLFD .CHVTB .CHFFD .CHCRT .CHCNU .CHCNZ .CHESC .CHDEL FL.RUB FL.OVW FL.WLD FL.RIB FL.EXR FL.ZER FL.IO FL.LDE FL.FFL FR.DEV FR.FIL FR.EXT FR.PTH FR.RBT FR.DMP FR.LOD FR.STA FR.1ST FR.ALL FX.CLR
;SYMBOLIC CHARACTER DEFINITIONS
.CHBEL==007 ;BELL
.CHCNH==010 ;BACKSPACE
.CHTAB==011 ;TAB
.CHLFD==012 ;LINE-FEED
.CHVTB==013 ;VERTICAL TAB
.CHFFD==014 ;FORM FEED
.CHCRT==015 ;CARRIAGE RETURN
.CHCNU==025 ;CONTROL U
.CHCNZ==032 ;CONTROL Z
.CHESC==033 ;ESCAPE
.CHDEL==177 ;DELETE
;FLAGS IN S. NOTE THAT THE FR.XXX FLAGS MUST BE IN THE SAME ORDER
;AS SWTTAB SINCE THE OFFSET INTO SWTTAB IS USED TO SET THE BIT IN S.
FL.RUB==1B0 ;CURRENTLY PROCESSING RUBOUT
FL.OVW==1B1 ;IGNORE UNPROCESSED DUMPS
FL.WLD==1B2 ;DEVICE IS WILD
FL.RIB==1B3 ;SKIP 1 BLOCK IN SELBLK SO THAT WE SKIP THE RIB
FL.EXR==1B4 ;READING IN AN EXTENDED RIB
FL.ZER==1B5 ;ALREADY ZEROED CORE
FL.IO==1B6 ;1 IF DOING OUTPUT, 0 IF DOING INPUT
FL.LDE==1B7 ;ERROR BEING PROCESSED WAS FROM LOAD, NOT DUMP
FL.FFL==1B8 ;FOUND FILE IN FNDFIL
FR.DEV==1B18 ;DEVICE SEEN
FR.FIL==1B19 ;FILENAME SEEN
FR.EXT==1B20 ;EXTENSION SEEN
FR.PTH==1B21 ;PATH SEEN
FR.RBT==1B32 ;/REBOOT SEEN
FR.DMP==1B33 ;/DUMP SEEN
FR.LOD==1B34 ;/LOAD SEEN
FR.STA==1B35 ;/START SEEN
FR.1ST==1B35 ;RIGHT-MOST BIT OF SWITCH BITS. SHIFT THIS BIT BY THE
;OFFSET INTO SWTTAB TO SET THE APPROPRIATE SWITCH BIT
FR.ALL==FR.DEV!FR.FIL!FR.EXT!FR.PTH!FR.RBT!FR.DMP!FR.STA!FR.LOD
;ALL PARSE BITS
FX.CLR==FL.RUB!FL.OVW!FL.WLD!FR.ALL ;BITS TO CLEAR ON ENTRY TO PARSE
;MONITOR PARAMETERS WHICH MUST AGREE WITH COMMON/COMMOD. ;⊗ HOMNAM HOMSNM HOMLUN HOMBSC HOMSCU HOMCNP HOMCLP HOMBPC HOMREF HOMMFD HOMCOD CODHOM HOMSLF RIBFIR RIBPPN RIBNAM RIBEXT RIBSIZ RIBSTS RIPDMP RIBXRA RIPNUB RIBCOD CODRIB RIBSLF BOOTSA BOOTWD LBNHOM LB2HOM LBOBAT LIMLVL MBTCOM MAXPGS .EPHSB
;
;HOME BLOCK DEFINITIONS
HOMNAM==0 ;SIXBIT/HOM/
HOMSNM==4 ;SIXBIT STRUCTURE NAME
HOMLUN==10 ;LOGICAL UNIT NUMBER WITHIN FILE STRUCTURE
HOMBSC==14 ;BLOCKS PER SUPERCLUSTER
HOMSCU==15 ;SUPER CLUSTERS PER UNIT
HOMCNP==16 ;BYTE POINTER TO CLUSTER COUNT IN RETRIEVAL PTR
HOMCLP==20 ;BYTE POINTER TO CLUSTER ADDRESS IN RET. PTR
HOMBPC==21 ;BLOCKS PER CLUSTER
HOMREF==23 ;NON-ZERO IF STRUCTURE NEEDS REFRESHING
HOMMFD==46 ;LOGICAL BLOCK NUMBER IN STR OF RIB FOR MFD
HOMCOD==176 ;CONTAINS UNLIKELY CODE
CODHOM==707070 ;THE CODE
HOMSLF==177 ;SELF BLOCK POINTER
;RIB DEFINITIONS
RIBFIR==0 ;AOBJN POINTER TO FIRST RETRIVAL POINTER IN RIB
RIBPPN==1 ;PPN OF FILE
RIBNAM==2 ;SIXBIT FILENAME
RIBEXT==3 ;SIXBIT EXTENSION
RIBSIZ==5 ;SIZE OF FILE IN WORDS
RIBSTS==17 ;STATUS BITS
RIPDMP==100000 ;THIS FILE CONTAINS AN UNPROCESSED DUMP
RIBXRA==34 ;POINTER TO NEXT EXTENDED RIB
RIPNUB==400000 ;NEW UNIT POINTER IN RETRIEVAL POINTER
RIBCOD==176 ;CONTAINS UNLIKELY CODE
CODRIB==777777 ;THE CODE
RIBSLF==177 ;SELF BLOCK POINTER
;MISCELANEOUS DEFINITIONS
BOOTSA==21 ;PHYSICAL ADDRESS FROM WHICH BOOT LOADED THE
; MONITOR. USED TO FIND MONITOR FILESPEC
BOOTWD==22 ;APRID OR CONI PAG, OF CPU ON WHICH BOOT WAS
; RUN. ALSO USED AS CHANNEL COMMAND PAIR FOR
; RH10'S.
LBNHOM==1 ;BLOCK ADDRESS OF FIRST HOME BLOCK
LB2HOM==12 ;BLOCK ADDRESS OF SECOND HOME BLOCK
LBOBAT==1 ;OFFSET OF BAT BLOCK FROM HOME BLOCK
LIMLVL==5 ;NUMBER OF SFD'S
MBTCOM==411 ;COMMUNICATIONS WORD IN LOW CORE FOR REBOOT
;REQUESTS. CONTAINS THE PHYSICAL PAGE NUMBER
;OF WHERE TO PUT BOOT DURING REBOOT PROCESSING
MAXPGS==<FTKI10&↑D8192>!<FTKL10&↑D8192>!<FTKS10&↑D1024>
;MAXIMUM NUMBER OF PAGES POSSIBLE IN MEMORY
.EPHSB==424 ;KS10 HALT STATUS BLOCK ADDRESS
;MISCELANEOUS HARDWARE PARAMETERS ;⊗ IT.DON IT.BSY APRRST CLRAPR PDLLEN LINBFL BLKSIZ PAGSIZ MAXUNI P2BLSH B2WLSH W2BLSH P2WLSH W2PLSH .VBOOT .VPAG0 .VMOVE .VZERO .MBOOT .MPAG0 .MMOVE .MZERO
IT.DON==1B30 ;KI10 CONI CTY, INPUT DONE
IT.BSY==1B31 ;KI10 CONI CTY, OUTPUT BUSY
APRRST==<FTKI10&321300>!<FTKL10&327760>!<FTKS10&221700>
;CONO BITS TO CLEAR THE WORLD
CLRAPR==<FTKI10&300>!<FTKL10&127700>!<FTKS10&021700>
;CONO BITS TO CLEAR APR ERROR FLAGS
;MISCELANEOUS PARAMETERS
PDLLEN==↑D36 ;SIZE OF PDL
LINBFL==↑D16 ;SIZE OF COMMAND LINE BUFFER IN WORDS
BLKSIZ==200 ;SIZE OF A DISK BLOCK
PAGSIZ==1000 ;SIZE OF A PAGE
MAXUNI==↑D8 ;MAX NUMBER OF UNITS ON A CONTROLLER
P2BLSH==2 ;AMOUNT TO LSH A PAGE COUNT TO GET BLOCKS
B2WLSH==↑D7 ;AMOUNT TO LSH A BLOCK COUNT TO GET WORDS
W2BLSH==-B2WLSH ;AMOUNT TO LSH A WORD COUNT TO GET BLOCKS
P2WLSH==↑D9 ;AMOUNT TO LSH A PAGE NUMBER TO GET WORDS
W2PLSH==-P2WLSH ;AMOUNT TO LSH A WORD COUNT TO GET PAGES
.VBOOT==750000 ;VIRTUAL ADDRESS AT WHICH MOST OF BOOT
; RUNS (AFTER CALL TO SETUP)
.VPAG0==730000 ;PAGE 0 MAPPED THROUGH THIS VIRUAL ADDRESS
;PAGE 1 MAPPED THROUGH .VPAG0+PAGSIZ
.VMOVE==732000 ;FIRST VIRTUAL ADDRESS USED TO MOVE BOOT TO
; HIGH CORE
.VZERO==732000 ;VIRTUAL ADDRESS USED TO ZERO CORE
DEFINE VMAP(ADDR),<<ADDR/PAGSIZ>/2>
.MBOOT==VMAP(.VBOOT) ;LEFT HALF WORD IN EPT MAPPING .VBOOT
.MPAG0==VMAP(.VPAG0) ;LEFT HALF WORD IN EPT MAPPING .VPAG0
;RIGHT HALF WORD MAPS .VPAG0+PAGSIZ
.MMOVE==VMAP(.VMOVE) ;LEFT HALF WORD IN EPT MAPPING .VMOVE
.MZERO==VMAP(.VZERO) ;LEFT HALF WORD IN EPT MAPPING .VZERO
IFN FTKL10!FTKI10,< ;⊗ CI.XDN CI.122 CI.1ER CI.1RA CI.2ER CI.2RA CO.XDN CO.XSX CO.XMI CO.1RB CO.1AE CO.2RB CO.2ME DO.XCR DO.XSR DI.XCE DI.XSM DI.XSB DO.XDS DO.XDT DO.XDC DO.1CR DO.2ST DO.XCL DO.XRP DO.XRD DO.XWT RH2TRA RH2JMP R2IOWL R2BCNT R2WCNT R1BCNT R1WCNT
;RH10/RH20 DEVICE DEPENDENT PARAMETERS
;CONI BITS
CI.XDN==10 ;TRANSFER DONE (RH10/RH20)
CI.122==4000,,0 ;22 BIT CHANNEL (RH10/DF10C)
CI.1ER==736320 ;DBPE, FXCEP, CHNER, OVR, DRE, ILC, PSFAIL,
;CBOV, RAE, BUSY (RH10)
CI.1RA==100 ;RAE (RH10)
CI.2ER==515000 ;DPE, LWCE, DR, RAE, DOE (RH20)
CI.2RA==4000 ;RAE (RH20)
;CONO BITS
CO.XDN==10 ;CLEAR DONE (RH10/RH20)
CO.XSX==20 ;STOP TRANSFER (RH10/RH20)
CO.XMI==2000 ;MASSBUS INIT (RH10/RH20)
CO.1RB==47 ;CONI BITS TO RESTORE - AIE, PIA (RH10)
CO.1AE==40 ;AIE (RH10)
CO.2RB==447 ;CONI BITS TO RESTORE - MBE, AIE, PIA (RH20)
CO.2ME==400 ;MASSBUS ENABLE (RH20)
;DATAI/DATAO BITS
DO.XCR==004400,,0 ;DRIVE CONTROL REGISTER (RH10/RH20)
DO.XSR==010400,,0 ;STATUS REGISTER (RH10/RH20)
DI.XCE==40000 ;COMPOSITE ERROR (RH10/RH20)
DI.XSM==172777 ;BIT MASK OF BITS TO CHECK FOR IN INITIALIZATION
DI.XSB==10700 ;LEGAL VALUE IN SR (MOL, DP, DR, VV)
DO.XDS==054000,,0 ;BLOCK ADDRESS REGISTER, LR (RH10/RH20)
DO.XDT==060000,,0 ;DRIVE TYPE REGISTER (RH10/RH20)
DO.XDC==124000,,0 ;DESIRED CYLINDER REGISTER, LR (RH10/RH20)
DO.1CR==404000,,0 ;CONTROL REGISTER (RH10)
DO.2ST==716200,,0 ;STCR, LR, RCLP, STORE (RH20)
DO.XCL==11 ;FUNCTION CODE FOR DRIVE CLEAR (RH10/RH20)
DO.XRP==21 ;FUNCTION CODE FOR READIN PRESET (RH10/RH20)
DO.XRD==71 ;FUNCTION CODE FOR READ (RH10/RH20)
DO.XWT==61 ;FUNCTION CODE FOR WRITE (RH10/RH20)
;MISCELANEOUS
RH2TRA==1B0 ;CHANNEL COMMAND OPCODE FOR TRANSFER (RH20)
RH2JMP==1B1 ;CHANNEL COMMAND OPCODE FOR JUMP (RH20)
R2IOWL==↑D69 ;NUMBER OF IOWDS TO ALLOCATE FOR THE LARGEST
;POSSIBLE TRANSFER
R2BCNT==↑D15 ;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
;IN ONE IOWD FOR AN RH20
R2WCNT==R2BCNT*BLKSIZ ;CORRESPONDING WORDCOUNT
R1BCNT==↑D127 ;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
;IN ONE IOWD FOR AN RH10
R1WCNT==R1BCNT*BLKSIZ ;CORRESPONDING WORDCOUNT
>;END IFN FTKL10!FTKI10
IFN FTKS10,< ;⊗ SO.UPR SO.VFT SO.RBT SO.USR SO.UBI SI.UER SO.CS1 SI.RDY SI.S1E SO.WC SO.BA SO.DA SO.CS2 SO.DS SO.DSM SO.DSB SI.DT SI.DSK SO.DC SO.DCL SO.RIP SO.WRT SO.RED RSBCNT
;RH11 DEVICE DEPENDENT PARAMETERS
;UBA ADDRESSES/BITS
SO.UPR==763000 ;UBA PAGING RAM ADDRESS
SO.VFT==140000 ;VALID+FAST XFER
SO.RBT==100,,277 ;BITS TO RESTORE IN CS1 AND UBA SR
SO.USR==763100 ;UBA STATUS REGISTER
SO.UBI==100 ;UNIBUS INIT
SI.UER==740000 ;TIME OUT, BMD, BUS PAR, NXD
;DRIVE ADDRESSES/BITS
SO.CS1==776700 ;CONTROL STATUS REGISTER 1
SI.RDY==200 ;READY AT END OF XFER
SI.S1E==140000 ;SC, TRE
SO.WC==776702 ;WORD COUNT REGISTER
SO.BA==776704 ;BUS ADDRESS REGISTER
SO.DA==776706 ;DESIRED ADDRESS REGISTER
SO.CS2==776710 ;CONTROL STATUS REGISTER 2
SO.DS==776712 ;DRIVE STATUS REGISTER
SO.DSM==172700 ;MASK FOR BITS RETURNED
SO.DSB==10700 ;LEGAL VALUE (MOL, DP, DR, VV)
SI.DT==776726 ;DRIVE TYPE REGISTER
SI.DSK==20000 ;DEVICE IS A DISK
SO.DC==776734 ;DESIRED CYLINDER REGISTER
;MISCELLANEOUS
SO.DCL==11 ;FUNCTION CODE FOR DRIVE CLEAR
SO.RIP==21 ;FUNCTION CODE FOR READIN PRESET
SO.WRT==61 ;FUNCTION CODE FOR WRITE
SO.RED==71 ;FUNCTION CODE FOR READ
RSBCNT==↑D252 ;MAX NUMBER OF BLOCKS WHICH MAY BE TRANSFERED
;AT ONE TIME BY THE RH11
>;END IFN FTKS10
SUBTTL MACRO DEFINITIONS ;⊗ OFFSET OFFSET LABEL BTSLOC
;MACRO DEFINITIONS TO ALLOW ASSEMBLY TO BE PHASED STARTING AT
;.VBOOT
DEFINE $PHASE,<
OFFSET==.-BOOTVA
OFFSET==.VBOOT+OFFSET
PHASE OFFSET
>
DEFINE $DEPHASE,<
XLIST
LIT
LIST
DEPHASE
>
DEFINE BLK(LABEL,SIZE),<
LABEL==BTSLOC
BTSLOC==BTSLOC+SIZE
BLOCK SIZE
>
;MACRO TO BUILD THE BOOT VERSION STRING
DEFINE VSTR(VER,EDT),<
ASCIZ/BOOT V'VER'(EDT)
/
>
;MACROS TO HELP IN INSERTING ENTRIES INTO THE PAGE MAP ;⊗ ZZ ZZ
DEFINE ONE41(FPAGE,LPAGE),<
ZZ==FPAGE
XLIST
REPEAT <<LPAGE-FPAGE+1>/2>,<
XWD PM.ACC+PM.WRT+ZZ,PM.ACC+PM.WRT+ZZ+1
ZZ==ZZ+2
>
LIST
>
DEFINE INSLOC(FLOC,LLOC,INSTN),<
XLIST
REPEAT <LLOC-FLOC+1>,<
INSTN
>
LIST
>
;MACRO TO CAUSE A PAUSE BETWEEN THE DATAO WHICH LOADS THE PREPARATION
;REGISTER AND THE DATAI WHICH READS THE VALUE FROM THE SPECIFIED
;REGISTER.
DEFINE STALL,<
IMULI P,1
IFN FTKL10,<
XLIST
IMULI P,1
LIST
>
>
SUBTTL DATA AREAS ;⊗ .RDATA BTSLOC EPTABS R2IOWD BTSLOC
;THE DATA AREA MUST BE THE FIRST THING IN THIS PROGRAM THAT GENERATES
;CODE TO INSURE THAT IT STARTS ON A PAGE BOUNDARY. IN ADDITION,
;THE EPT MUST BE THE FIRST THING IN THE DATA AREA FOLLOWED IMMEDIATELY
;BY THE BLOCKS FOR HOM, RIB, AND BUF, FOR THE SAME REASON. NOTE
;THAT IF ANY OF THE LAST THREE BLOCKS ARE SPLIT ACROSS A PAGE BOUNDARY
;THE I/O SUBROUTINES WILL NOT (NECESSARILY) WORK.
.RDATA==.VBOOT-. ;RELOCATABLE ADDRESS OF START OF DATA
BTSLOC==.VBOOT ;INITIALIZE MACROS
EPTABS: ;UNMAPPED ADDRESS OF EPT
BLK(EPT,0) ;PUT THIS HERE SO IT STARTS ON A PAGE BOUNDARY
BLOCK 200 ;0-177 MISCELANEOUS BLOCKS NOT FILLED IN
ONE41 (400,777) ;200-377=PAGES 400-777 IN EXEC MAP
ONE41 (340,377) ;400-417=PAGES 340-377 IN USER MAP
IFN FTKI10,<
JSR PFTRAP ;420=PAGE FAIL TRAP INSTRUCTION ON KI10
>
IFN FTKL10!FTKS10,<
BLOCK 1 ;420=UNUSED ON KL OR KS
>
JFCL ;421=ARITHMETIC OVERFLOW TRAP INSTRUCTION
JRST TRAP ;422=PDL OVERFLOW TRAP INSTRUCTION
JRST TRAP ;423=TRAP 3 TRAP INSTRUCTION
BLOCK 4 ;424-427 MUUO LOCATIONS
INSLOC (430,437,<EXP TRAP>) ;430-437=MUUO NEW PC WORDS
BLOCK 40 ;440-477=UNUSED
BLOCK 2 ;500-501=PAGE FAIL LOCATIONS ON KL AND KS
IFN FTKI10,<
BLOCK 1 ;502=UNUSED ON KI10
>
IFN FTKL10!FTKS10,<
EXP PFTRAP ;502=NEW PC WORD ON KL AND KS
>
BLOCK 75 ;503-577=UNUSED
IFN FTKI10,<
BLOCK 160 ;600-757=UNUSED ON KI10
>
IFN FTKL10!FTKS10,<
ONE41 (0,337) ;600-757=PAGES 0-377 ON KL AND KS
>
BLOCK 20 ;760-777=UNUSED
IFN FTKL10,<
R2IOWD==EPT+PAGSIZ-R2IOWL ;WHERE TO PUT RH20 IOWDS
>
BTSLOC==BTSLOC+PAGSIZ ;UPDATE PHASED ASSEMBLY COUNTER
BLK(HOM,BLKSIZ) ;HOM BLOCK FOR CURRENT UNIT ;⊗ SWTVLV SWTVLL FILSPE NXMTBE
BLK(RIB,BLKSIZ) ;RIB BLOCK FOR CURRENT FILE
BLK(BUF,BLKSIZ) ;WORK BUFFER
;THE FOLLOWING LOCATIONS MUST REMAIN IN THIS ORDER. (SEE BOOTFX IN
;ONCE)
BLK(FILSPC,0) ;FIRST WORD CLEARED EACH TIME THROUGH PARSE
BLK(DEV,1) ;DEVICE NAME
BLK(FILNAM,1) ;FILENAME
BLK(EXT,1) ;EXTENSION
BLK(PTHBLK,7) ;PATH BLOCK
;END OF ORDER DEPENDENT LOCATIONS
SWTVLV:
BLK(SWTVAL,0) ;START OF BLOCK OF SWITCH VALUES
BLK(STSA,1) ;START ADDRESS GIVEN IN /START
SWTVLL==.-SWTVLV
FILSPE==BTSLOC-1 ;END OF AREA TO CLEAR EACH TIME THROUGH PARSE
BLK(EPTADR,1) ;PHYSICAL ADDRESS OF OUR EPT
BLK(CPEBR,1) ;ARGUMENT TO CHANGE THE EPT TO IT'S CURRENT VALUE
BLK(MEMPSZ,1) ;NUMBER OF PAGES IN MEMORY
BLK(LUNPOS,1) ;LOGICAL UNIT NUMBER WITHIN STR
BLK(DRVBPC,1) ;BLOCKS/CYLINDER ON THIS UNIT \*** KEEP
BLK(DRVBPT,1) ;BLOCKS/TRACK ON THIS UNIT /*** TOGETHER
BLK(BLKCNT,1) ;NUMBER BLOCKS LEFT IN THIS GROUP
BLK(BLKADR,1) ;CURRENT BLOCK ADDRESS
BLK(BLKNUM,1) ;CURRENT RELATIVE BLOCK NUMBER IN FILE
BLK(SAVFIR,1) ;COPY OF RIBFIR FROM CURRENT RIB
BLK(SAVSIZ,1) ;COPY OF RIBSIZ FROM CURRENT RIB
BLK(BTSPDL,PDLLEN) ;PUSH DOWN LIST
BLK(CMDPTR,1) ;BYTE POINTER TO COMMAND BUFFER
BLK(CMDBUF,LINBFL) ;COMMAND LINE BUFFER
BLK(NXMTAB,<MAXPGS/↑D36>+1) ;OUR COPY OF NXMTAB
NXMTBE==BTSLOC-1 ;END OF NXMTAB
;HERE AFTER BEING LOADED INTO MEMORY. WE ARE (PROBABLY) RUNNING ;⊗ BOOT
;UNPAGED AT THIS POINT SO WE MUST DO SOMETHING ABOUT THAT FIRST.
BOOT: CONO APR,APRRST ;BLAST THE PROCESSOR
IFN FTKL10,<
CONO APR,APRRST ;-20F STARTS BOOTSTRAPS AT ENTRY+1
>
CONO PI,PI.CPI!PI.OFF ;BLAST THE PI SYSTEM
IFN FTKI10,<
MOVEI T1,PG.LEB!PG.EAT!<EPTABS/PAGSIZ> ;GET BITS TO SET THE EBR
MOVSI T4,<(PG.LUB)>!<EPTABS/PAGSIZ> ;AND TO SET THE UBR
DATAO PAG,T1 ;TURN ON PAGING, MAP US 1 FOR 1
DATAO PAG,T4 ;SET THE UPT TO THE SAME PAGE
>
IFN FTKL10,<
MOVEI T1,LG.TEN!<EPTABS/PAGSIZ> ;GET BITS TO SET THE EBR
MOVSI T4,(LG.LAB!LG.LPC!LG.LUB) ;FLAG BITS TO LOAD THE UBR
HRRI T4,LG.IAM!<EPTABS/PAGSIZ> ;AND THE PAGE NUMBER
CONO PAG,(T1) ;TURN ON PAGING, MAP US 1 FOR 1
DATAO PAG,T4 ;SET THE UPT TO THE SAME PAGE
CONO DTE0,PILDEN!0 ;TURN OFF DTE PIA
>
IFN FTKS10,<
WREBR 0 ;TURN OFF PAGING, MAKE THE KS HAPPY
MOVEI T1,SG.TEN!<EPTABS/PAGSIZ> ;GET BITS TO SET THE EBR
MOVSI T4,(SG.LAB!SG.LUB) ;FLAG BITS TO LOAD THE UBR
HRRI T4,<EPTABS/PAGSIZ> ;AND THE PAGE NUMBER
WREBR (T1) ;TURN ON PAGIN, MAP US 1 FOR 1
WRUBR T4 ;SET THE UPT TO THE SAME PAGE
MOVEI T2,.EPHSB ;GET HALT STATUS BLOCK ADDRESS
WRHSB T2 ;WRITE IT
>
MOVEM T1,CPEBR-.RDATA ;STORE BITS TO CHANGE EBR FOR LATER
MOVEI T2,PM.ACC!PM.WRT!0 ;MAKE PAGE 0 AND 1 ADDRESSABLE
HRLI T2,1(T2) ;AS VIRTUAL ADDRESSES .VPAG0
MOVSM T2,EPT+.MPAG0-.RDATA ;AND .VPAG0+PAGSIZ IN OUR MAP
MOVEI T2,EPTABS ;GET PHYSICAL ADDRESS OF OUR EPT
MOVEM T2,EPTADR-.RDATA ;STORE FOR LATER
LSH T2,W2PLSH ;CONVERT TO A PAGE NUMBER
HRLI T2,-BOOPGS ;MAKE AOBJN POINTER
TRO T2,PM.ACC+PM.WRT ;SET FLAG BITS
MOVSI T3,(POINT 18,0) ;BUILD BYTE POINTER TO EPT (NO LITERAL
HRRI T3,EPT+.MBOOT-.RDATA ; TO GET AROUND A LINK BUG)
IDPB T2,T3 ;MAP BOOT IN .VBOOT ADDRESS SPACE
AOBJN T2,.-1 ; ADDRESS SPACE
MOVE T2,CHGEBR-.RDATA ;GET INSTRUCTION TO CHANGE THE EBR
MOVSI T3,(JRST) ;SETUP JRST TO GET BACK AFTER
HRRI T3,MAPPED ; WE'RE MAPPED
JRST T2 ;CHANGE THE EBR, COME BACK MAPPED
;HERE WHEN THE .VBOOT ADDRESS SPACE HAS BEEN MAPPED TO DO SOME ONCE ;⊗ MAPPED
;ONLY INITIALIZATION BEFORE FALLING INTO RLDMON.
$PHASE
MAPPED: MOVEI P,BTSPDL ;SETUP A PDL
IFN FTKL10,<
SETZM EPT+DTEEPW ;CLEAR DTE EXAMINE/PROTECTION WORD
SETZM EPT+DTEMTI ;CLEAR INPUT READY FLAG
MOVSI T3,DT.ESP ;BIT TO CAUSE -20F TO ENTER SECONDARY
HRRI T3,DTEFLG ;IN THIS WORD
PUSHJ P,DODTE ;EXECUTE THE COMMAND
>
IFN FTKS10,<
SETZM .VPAG0+CTYIWD ;CLEAR INPUT AVAILABLE WORD
SETZM .VPAG0+CTYOWD ;AND OUTPUT PRESENT WORD
SETZM .VPAG0+RLWORD ;AND FLAGS WORD
>
MOVEI S,0 ;ZERO FLAGS
PUSHJ P,SUNXMT ;LOOK AT MEMORY AND SETUP NXMTAB
MOVEI T1,VERMSG ;POINT AT VERSION STRING
PUSHJ P,PRMSG ;TELL HIM THAT WE'RE HERE
;; PJRST RLDMON ;FALL INTO RLDMON
;ROUTINE TO PROMPT THE USER AND DUMP/LOAD/RELOAD THE MONITOR. CALL ;⊗ RLDMON RLDMO1 RLDMO2
;AFTER SETTING UP THE MAP SO THAT WE ARE RUNNING IN THE .VBOOT ADDRESS
;SPACE. EXITS TO THE START ADDRESS OF THE NEW MONITOR.
;CALL: PJRST RLDMON
RLDMON: MOVEI P,BTSPDL ;SETUP PDL AGAIN IN CASE OF TRAP
MOVEI T1,[ASCIZ/BOOT>/] ;OUR PROMPT
PUSHJ P,REDLIN ;TYPE IT AND READ IN RESPONSE
PUSHJ P,PARSE ;PARSE THE COMMAND
JRST RLDMON ;SYNTAX ERROR
TRNE S,FR.DMP ;/DUMP SEEN?
JRST [PUSHJ P,DODUMP ;YES, TAKE A DUMP
JRST RLDMON] ;AND GO BACK AROUND
TRNE S,FR.STA ;/START SEEN?
TRNE S,FR.ALL-FR.STA ;AND NOTHING ELSE?
CAIA ;NO
JRST RLDMO1 ;YES, JUST START UP MONITOR
PUSHJ P,DOLOAD ;LOAD NEW MONITOR
JRST RLDMON ;ERROR DETECTED
TRNE S,FR.LOD ;/LOAD SPECIFIED?
JRST RLDMON ;YES, DON'T START
RLDMO1: TRNE S,FR.RBT ;THIS A /REBOOT REQUEST?
JRST RLDMO2 ;YES, DON'T CHANGE CORE
MOVE T1,EPTADR ;GET PHYSICAL ADDRESS OF EPT
ADDI T1,FILSPC-EPT-140 ;COMPUTE BOOTSA POINTER
TLO T1,(1B0) ;SET SIGN BIT SO MONITOR CAN TELL IT'S BOOT
MOVEM T1,.VPAG0+BOOTSA ;SO THAT BOOTFX CAN FIND THE MONITOR NAME
IFN FTKL10!FTKS10,<
APRID .VPAG0+BOOTWD ;STORE SERIAL NUMBER FOR SYSTRT
>
IFN FTKI10,<
CONI PAG,.VPAG0+BOOTWD ;DITTO FOR KI
>
MOVE 17,[CONO APR,200000] ;STORE CONO APR,200000 SO THAT
SKIPA T2,[MOVEM 17,FILSPC-140+1000] ;CONSISTENCY CHECKS WORK
RLDMO2: MOVSI T2,(JFCL) ;DON'T DO ANYTHING IF FROM REBOOT
SKIPN T4,STSA ;START ADDRESS SPECIFIED ON /START?
HRRZ T4,.VPAG0+.JBSA## ;NO, USE ADDRESS FROM FILE
HRLI T4,(JRST) ;MAKE IT A JRST
MOVE T3,CHGEBR ;GET INSTRUCTION TO CHANGE THE EBR
IFN FTKI10,<
MOVEI T1,PG.LEB ;TURN OFF PAGING KI STYLE
>
IFN FTKL10!FTKS10,<
MOVEI T1,0 ;TURN OFF PAGING KL/KS STYLE
>
JRST T2 ;TURN OFF PAGING AND START NEW MONITOR
CHGEBR: ;⊗ CHGEBR CHGUBR VERMSG
IFN FTKI10,<
DATAO PAG,T1 ;CHANGE THE EBR
>
IFN FTKL10,<
CONO PAG,(T1) ;CHANGE THE EBR
>
IFN FTKS10,<
WREBR (T1) ;CHANGE THE EBR
>
CHGUBR:
IFN FTKI10!FTKL10,<
DATAO PAG,T4 ;CHANGE THE UBR
>
IFN FTKS10,<
WRUBR T4 ;CHANGE THE UBR
>
;BUILD THE BOOT VERSION MESSAGE
VERMSG: VSTR (\BOOVER,\BOOEDT)
SUBTTL DUMP MONITOR ;⊗ ASKSTR DODUMP DODUM1 DODUM2 DODUM3 DODUM4
;ROUTINE TO DUMP THE SYSTEM. CALL WITH INITIAL FILESPEC ON
;WHICH TO DUMP IN THE FILESPEC AREA. ASKS THE USER FOR A NEW
;FILESPEC IF ERRORS ARE DETECTED.
;CALL: PUSHJ P,DODUMP
;RETURN+1 ALWAYS
ASKSTR: MOVEI T1,[ASCIZ/Filespec on which to dump: /]
PUSHJ P,REDLIN ;ASK WHERE HE WANTS THE DUMP
PUSHJ P,PARSE ;PARSE THE COMMAND
JRST ASKSTR ;TRY AGAIN
TRNN S,FR.ALL ;SEE ANYTHING AT ALL?
POPJ P, ;NO, LONE CR MEANS NO DUMP
TRO S,FR.DMP ;MAKE SURE DUMP FLAG IS SET
DODUMP: MOVE T1,[SIXBIT/CRASH/] ;DEFAULT FILENAME IS CRASH
TRNN S,FR.FIL ;SEE A FILENAME?
MOVEM T1,FILNAM ;NO, USE DEFAULT
TLNN S,(FL.WLD) ;WILD STR?
JRST DODUM2 ;NO, USE THE ONE HE SAID
MOVE P1,['DSKA '-10000] ;GET DISK NAME TO INCREMENT TO DSKA
DODUM1: ADDI P1,10000 ;STEP TO NEXT DISK NAME
CAMN P1,[SIXBIT/DSKO/] ;LOOKED AT THE LAST ONE?
JRST DODUM4 ;YES, GIVE UP
MOVEM P1,DEV ;SAVE NAME OF DEVICE
DODUM2: TLZA S,(FL.OVW) ;DON'T ALLOW OVERWRITING
DODUM3: TLO S,(FL.OVW) ;OVERWRITE IF HE SAYS TO
PUSHJ P,DUMP ;TRY TO DUMP THE MONITOR
JRST DMPERR ;FAILED, ANALYZE ERROR AND TRY TO RECOVER
POPJ P, ;COMPLETED SUCCESSFULLY, RETURN
DODUM4: MOVEI T1,[ASCIZ/?Unable to find a file on which to dump
/]
PUSHJ P,PRMSG ;PRINT MESSAGE
MOVEI T1,[ASCIZ/Do you want to keep this dump? /]
PUSHJ P,ASKYN ;ASK HIM
POPJ P, ;HE SAYS NO
JRST ASKSTR ;ASK ON WHAT STR TO DUMP
;HERE IF AN ERROR IS DETECTED IN THE DUMP OR LOAD. USE THE ERROR ;⊗ LODERR DMPERR DMPER1 DMPER2 DMPER3
;CODE RETURNED IN T1 TO INDEX INTO EMSTAB AND PRINT A MESSAGE.
;FOR DUMP, INDEX INTO DMPDSP AND DISPATCH TO THE ROUTINE TO
;HANDLE THE ERROR.
LODERR: TLOA S,(FL.LDE) ;FLAG LOAD ERROR
DMPERR: TLZ S,(FL.LDE) ;CLEAR BIT FOR DUMP ERRORS
TLNE S,(FL.WLD) ;WILD STRUCTURE?
TLNE S,(FL.FFL) ;YES, DID WE FIND THE FILE ON THIS STR?
JRST DMPER1 ;YES, PROCEED NORMALLY
CAIG T1,FNFOFS ;NO, IS THIS ERROR JUST FILE OR STR NOT FOUND?
JRST DMPER2 ;YES, DON'T PRINT MESSAGE
DMPER1: PUSH P,T1 ;SAVE CODE FOR LATER
HRRZ T1,EMSTAB(T1) ;GET MESSAGE ADDRESS
PUSHJ P,PRMSG ;PRINT IT
PUSHJ P,PRFILE ;PRINT FILENAME
PUSHJ P,PRCRLF ;END THE LINE
POP P,T1 ;RESTORE ERROR CODE
DMPER2:
IFN FTKI10,<
CONSZ APR,IP.PAR!IP.NXM ;NXM OR PARITY ERROR?
>
IFN FTKL10,<
CONSZ APR,LP.SBE!LP.NXM!LP.PAR ;NXM OR PARITY ERROR?
>
IFN FTKS10,<
CONSZ APR,SP.NXM!SP.HMP ;NXM OR PARITY ERROR?
>
JRST DMPER3 ;YES
TLNN S,(FL.LDE) ;SKIP IF LOAD ERROR
SKIPA T1,DMPDSP(T1) ;GET DISPATCH ADDRESSES FOR DUMP
MOVE T1,LODDSP(T1) ;DITTO FOR LOAD
TLNN S,(FL.WLD) ;DOING WILD STR?
MOVSS T1 ;YES, USE LH DISPATCH ADDRESSES
JRST (T1) ;GO RECOVER
;HERE ON A NXM OR PARITY ERROR DETECTED IN THE CONI APR TO PRINT THE
;APR STATUS AND GIVE UP.
DMPER3: MOVEI T1,[ASCIZ/?NXM or memory parity error detected/]
PUSHJ P,PRMSG ;TELL WHAT HAPPENED
PUSHJ P,PRTAPR ;PRINT APR STATUS
CONO APR,CLRAPR ;RESET THE BITS
POPJ P, ;AND GIVE UP
;TABLE OF ERROR MESSAGES INDEXED BY THE ERROR CODE RETURNED IN T1. ;⊗ EMSTAB FNFOFS EMSTBL DMPDSP DMPDSL LODDSP LODDSL STRFUL
;THE STRUCTURE NOT FOUND AND FILE NOT FOUND ERRORS MUST BE THE FIRST
;IN THE TABLE BEFORE THE LABEL FNFOFS SO THAT WE CAN AVOID PRINTING
;A FILE/STRUCTURE NOT FOUND MESSAGE FOR EVERY STRUCTURE WHEN THE
;OPERATOR SPECIFIES A WILD STRUCTURE NAME.
EMSTAB: [ASCIZ/%Structure not found for /]
[ASCIZ/%File not found /]
FNFOFS==.-EMSTAB-1
[ASCIZ/%Unprocessed dump on /]
[ASCIZ/%Unexpected end-of-file on /]
[ASCIZ\%I/O error on \]
[ASCIZ/%Bad directory format for /]
[ASCIZ/%Memory configuration too complicated for /]
[ASCIZ/%Not a REBOOTable dump /]
EMSTBL==.-EMSTAB
;DISPATCH TABLES INDEXED BY ERROR CODE. LH GIVES THE DISPATCH ADDRESS
;IF AN EXPLICIT STRUCTURE WAS GIVEN, RH GIVES THE DISPATCH ADDRESS IF
;THE STRUCTURE WAS WILD (DSKA-DSKO)
DMPDSP: XWD ASKSTR,DODUM1 ;STRUCTURE NOT FOUND
XWD ASKSTR,DODUM1 ;FILE NOT FOUND
XWD STRFUL,DODUM1 ;UNPROCESSED DUMP
XWD ASKSTR,DODUM1 ;UNEXPECTED EOF
XWD ASKSTR,DODUM1 ;I/O ERROR
XWD ASKSTR,DODUM1 ;BAD DIRECTORY FORMAT
XWD ASKSTR,DODUM1 ;MEMORY CONFIGURATION TOO COMPLICATED
XWD ASKSTR,DODUM1 ;NOT A REBOOTABLE CRASH
DMPDSL==.-DMPDSP
LODDSP: XWD CPOPJ,DOLOA1 ;STRUCTURE NOT FOUND
XWD CPOPJ,DOLOA1 ;FILE NOT FOUND
XWD CPOPJ,DOLOA1 ;UNPROCESSED DUMP
XWD CPOPJ,DOLOA1 ;UNEXPECTED EOF
XWD CPOPJ,DOLOA1 ;I/O ERROR
XWD CPOPJ,DOLOA1 ;BAD DIRECTORY FORMAT
XWD CPOPJ,DOLOA1 ;MEMORY CONFIGURATION TOO COMPLICATED
XWD CPOPJ,DOLOA1 ;NOT A REBOOTABLE CRASH
LODDSL==.-LODDSP
IF2 <IFN EMSTBL-DMPDSL+LODDSL-ERRTBL,<
PRINTX ?Discrepency in lengths of EMSTAB, DMPDSP, LODDSP, ERRTAB
>>
;HERE IF AN EXPLICIT STR WAS GIVEN AND AN UNPROCESSED DUMP WAS FOUND
;ON THAT STR.
STRFUL: MOVEI T1,[ASCIZ/Do you want to overwrite it? /]
PUSHJ P,ASKYN
JRST ASKSTR
JRST DODUM3
;ROUTINE TO DUMP THE MONITOR ONTO THE CRASH FILE SPECIFIED IN THE ;⊗ DUMP DUMP1 DUMP2
;COMMAND STRING. DOES 5 ONE BLOCK TRANSFERS TO WRITE THE 4 BLOCKS
;OF THE DIRECTORY PLUS WORDS 0-177 OF PAGE 0 (SINCE THE RH20 CAN'T
;READ/WRITE ADDRESS 0) AND THEN DOES AS FEW TRANSFERS AS NECESSARY
;FOR EACH GROUP POINTER IN THE RIB. (GENERALLY ONLY 1). CALL WITH
;STRUCTURE NAME IN DEV.
;CALL: PUSHJ P,DUMP
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL
DUMP: PUSHJ P,SAVE2 ;SAVE P1-P2
PUSHJ P,FNDFIL ;FIND CRASH FILE FOR THIS STR
POPJ P, ;NOT FOUND
MOVEI T1,[ASCIZ/[Dumping on /]
PUSHJ P,PRMSG ;TELL THE OPERATOR WHAT
PUSHJ P,PRFILE ; WE'RE DOING
PUSHJ P,PRRBCR ;END THE LINE
MOVEI T1,RIPDMP ;GET "UNPROCESSED DUMP BIT"
TLNN S,(FL.OVW) ;DOES CALLER CARE?
TDNN T1,RIB+RIBSTS ;YES, IS BIT SET IN RIB?
CAIA ;NO, OR DOESN'T CARE
JRST UPDERR ;YES, GIVE ERROR RETURN
IORM T1,RIB+RIBSTS ;SET BIT IN RIB
PUSHJ P,WRTRIB ;REWRITE RIB
POPJ P, ;FAILED
PUSHJ P,CLRBUF ;CLEAR BUFFER AREA
MOVSI P3,-BLKSIZ ;MAKE AOBJP POINTER TO BUF
MOVEI P4,1 ;FIRST FILE PAGE IS 1
MOVEI P2,0 ;FIRST CORE PAGE IS 0
DUMP1: PUSHJ P,FNDPGS ;FIND NEXT GROUP OF CONTIGUOUS PAGES
JUMPLE P1,DUMP3 ;DONE IF NONE FOUND
MOVE T1,P1 ;COPY NUMBER OF PAGES TO T1
SUBI T1,1 ;REPEAT COUNT FOR LAST HUNK
ROT T1,-↑D9 ;NUMBER OF 256K HUNKS+REPEAT COUNT IN LH
MOVEI T2,1(T1) ;T2:=NUMBER OF DESCRIPTORS
DUMP2: AOBJP P3,MCCERR ;GO IF TOO MANY DESCRIPTORS
HRRZM P4,BUF(P3) ;STORE FILE PAGE NUMBER IN BUF
MOVEI T3,(P2) ;COPY CORE PAGE NUMBER TO T3
HRLI T3,770βX00 ;512 PAGES IN THIS HUNK
AOBJP P3,MCCERR ;GO IF TOO MANY DESCRIPTORS
MOVEM T3,BUF(P3) ;STORE IN BUFFER
ADDI P2,<↑D256*↑D1024>/PAGSIZ ;INCR CORE PAGE
ADDI P4,<↑D256*↑D1024>/PAGSIZ ;DITTO FOR FILE PAGE
SOJG T2,DUMP2 ;LOOP FOR ALL DESCRIPTORS
HLLM T1,BUF(P3) ;CORRECT REPEAT COUNT IN LAST DESCRIPTOR
LSH T1,-<↑D9+↑D18> ;RIGHT JUSTIFY REPEAT COUNT
MOVNI T1,-777(T1) ;HAVE TO BACK OFF ON CORE AND FILE PAGE
SUBI P2,(T1) ; NUMBERS TO REFLECT THE (POSSIBLY)
SUBI P4,(T1) ; PARTIAL ALLOCATION IN THE LAST DESCRIPTOR
JRST DUMP1 ;LOOP FOR MORE
DUMP3: MOVE T1,[SV.END,,1] ;GET END OF DESCRIPTOR MARKER ;⊗ DUMP3 DUMP4 DUMP5 DUMP6
AOBJP P3,MCCERR ;GO IF TOO MANY DESCRIPTORS
MOVEM T1,BUF(P3) ;STORE IN BUFFER
HRLI P3,SV.DIR ;MAKE P3 BE 1ST WORD OF DIRECTORY
MOVEM P3,BUF ;AND STORE IT THERE
PUSHJ P,WRTBUF ;WRITE BUFFER TO FILE
POPJ P, ;NO POINTERS OR WRITE FAILURE
PUSHJ P,CLRBUF ;CLEAR BUFFER AGAIN
MOVEI P1,3 ;NEED TO WRITE 3 BLOCKS OF ZEROS
DUMP4: PUSHJ P,WRTBUF ; TO COMPLETE DIRECTORY
POPJ P, ;NO POINTERS OR WRITE FAILURE
SOJG P1,DUMP4 ;LOOP FOR ALL
MOVE T1,[.VPAG0,,BUF] ;SETUP TO BLT WORD 0-177 TO BUF
BLT T1,BUF+BLKSIZ-1 ;DO SO
PUSHJ P,WRTBUF ;WRITE IT
POPJ P, ;NO POINTERS OR WRITE FAILURE
MOVEI P2,0 ;START WITH ADDRESS 0
DUMP5: LSH P2,W2PLSH ;CONVERT TO PAGE NUMBER
PUSHJ P,FNDPGS ;FIND NEXT GROUP OF CONTIGUOUS PAGES
JUMPLE P1,CPOPJ1 ;DONE IF NO MORE
LSH P2,P2WLSH ;CONVERT BACK TO ADDRESS
LSH P1,P2BLSH ;CONVERT PAGES TO BLOCKS
JUMPN P2,DUMP6 ;GO IF NOT DOING PAGE ZERO
ADDI P2,BLKSIZ ;COMPENSATE FOR WORDS 0-177
SUBI P1,1 ; WHICH WERE WRITTEN ABOVE
DUMP6: JUMPLE P1,DUMP5 ;LOOP IF NO MORE BLOCKS IN THIS CHUNK
MOVE T1,P1 ;COPY NUMBER OF BLOCKS WE WANT TO XFER
PUSHJ P,SELBLK ;SETUP TO DO THAT MANY
JRST EOFERR ;RAN OUT OF POINTERS
MOVE R,P2 ;START AT THIS ADDRESS
MOVE P1,T1 ;COPY NUMBER LEFT INTO P1 FOR LOOP TEST
MOVE T1,M ;GET NUMBER OF BLOCKS WE CAN DO
LSH T1,B2WLSH ;CONVERT TO WORDS
ADD P2,T1 ;INCREMENT ADDRESS FOR NEXT TIME
PUSHJ P,@WRTTAB(W) ;DO THE WRITE
JRST IOFERR ;WRITE ERROR
JRST DUMP6 ;LOOP FOR ALL OF CORE
SUBTTL RELOAD MONITOR ;⊗ DOLOAD DOLOA1 DOLOA2 DOLOA3
;ROUTINE TO RELOAD THE MONITOR FROM A FILE ON DISK. CALL WITH
;THE FILESPEC FROM WHICH TO LOAD SETUP IN THE FILESPEC AREA.
;CALL: PUSHJ P,DOLOAD
;RETURN+1 IF ERRORS DETECTED WITH MESSAGE ALREADY ISSUED
;RETURN+2 IF LOAD WAS SUCCESSFUL
DOLOAD: MOVE T1,[SIXBIT/SYSTEM/] ;DEFAULT FILENAME IS SYSTEM
TRNE S,FR.RBT ;UNLESS A /REBOOT REQUEST
MOVE T1,[SIXBIT/CRASH/] ;IN WHICH CASE FILENAME IS CRASH
TRNN S,FR.FIL ;SEE A FILENAME?
MOVEM T1,FILNAM ;NO, USE DEFAULT
TLNN S,(FL.WLD) ;WILD STR?
JRST DOLOA2 ;NO, USE THE ONE HE GAVE
MOVE P1,['DSKA '-10000] ;GET FIRST DISK NAME
DOLOA1: ADDI P1,10000 ;STEP TO NEXT DISK NAME
CAMN P1,[SIXBIT/DSKO/] ;LOOKED AT THEM ALL?
JRST DOLOA3 ;YES, GIVE UP
MOVEM P1,DEV ;STORE STR NAME
DOLOA2: PUSHJ P,LOAD ;LOAD IT
JRST LODERR ;GIVE ERROR MESSAGE AND RETURN
JRST CPOPJ1 ;GIVE SKIP RETURN
DOLOA3: MOVEI T1,[ASCIZ/?No file found on any structure
/]
PJRST PRMSG ;GIVE ERROR MESSAGE AND RETURN
;ROUTINE TO LOAD A NEW MONITOR INTO CORE. CALL WITH THE FILESPEC AREA ;⊗ LOAD LOAD1 LOAD2 LOAD3 LOAD4 LOAD5 LOAD6 LOAD7
;CONTAINING THE FILE TO BE LOADED.
;CALL: PUSHJ P,LOAD
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL
LOAD: PUSHJ P,SAVE2 ;SAVE P1-P2
PUSHJ P,FNDMON ;FIND THE MONITOR, READ EXE DIRECTORY
POPJ P, ;FAILED, RETURN CODE IN T1
PUSHJ P,FINDHI ;FIND PHYSICAL PAGE # OF TOP OF CORE
PUSHJ P,MOVBTS ;MOVE US TO THE TOP OF CORE
TRNE S,FR.RBT ;THIS A REBOOT?
SKIPA T1,[[ASCIZ/[Reloading from /]] ;YES, CHANGE THE MESSAGE
MOVEI T1,[ASCIZ/[Loading from /]
PUSHJ P,PRMSG ;TELL WHAT'S HAPPENING
PUSHJ P,PRFILE ;PRINT FILENAME
PUSHJ P,PRRBCR ;END THE LINE
MOVEI P3,0 ;START WITH CORE ADDRESS OF ZERO
LOAD1: LDB P2,[POINT 9,1(P1),8] ;GET REPEAT COUNT FOR THIS ENTRY
ADDI P2,1 ;MAKE IT TOTAL PAGE COUNT
LSH P2,P2BLSH ;COMPUTE BLOCK COUNT
HRRZ P4,0(P1) ;GET FILE PAGE NUMBER
LSH P4,P2BLSH ;COMPUTE FILE BLOCK NUMBER
JUMPE P4,[LSH P2,B2WLSH ;IF ALLOCATED BUT ZERO PAGE, COMPUTE
ADD P3,P2 ; NUMBER OF WORDS IN THIS DESCRIPTOR
JRST LOAD7] ; UPDATE CORE ADDRESS AND DO NEXT ONE
CAMGE P4,BLKNUM ;PAGE NUMBERS IN THE EXE DIRECTORY MUST
JRST BDFERR ; BE MONOTONICALLY INCREASING
LOAD2: PUSHJ P,POSFIL ;POSITION FILE TO THAT BLOCK
POPJ P, ;HIT EOF
LOAD3: SKIPGE 0(P1) ;THIS A HIGH SEG PAGE?
JRST LOAD5 ;YES, READ IN JUST AFTER LOW SEG
HRRZ P3,1(P1) ;GET CORE PAGE NUMBER
LSH P3,P2WLSH ;COMPUTE CORE ADDRESS
JUMPN P3,LOAD5 ;GO IF NOT ZERO
HRL P4,P2 ;REMEMBER NUMBER OF BLOCKS
MOVEI P2,PAGSIZ/BLKSIZ ; AND READ ONE PAGE
LOAD4: MOVEI P3,PAGSIZ ; STARTING AT 1000
LOAD5: PUSHJ P,REDBLK ;READ THE SPECIFIED BLOCKS
POPJ P, ;FAILED
HLRZ P2,P4 ;WERE WE READING 0-777
JUMPE P2,LOAD7 ; INTO 1000-1777?
TRNN S,FR.RBT ;DOING A REBOOT?
JRST LOAD6 ;NO, CONTINUE
SKIPN T2,.VPAG0+PAGSIZ+MBTCOM ;GET PAGE NUMBER OF COMM AREA
JRST NSSERR ;NOT A REBOOTABLE CRASH
TLZ T2,-1 ;CLEAR JUNK
PUSHJ P,MOVBTS ;MOVE US TO THOSE PAGES
SKIPA T1,[.VPAG0+PAGSIZ,,.VPAG0] ;SETUP TO BLT ENTIRE PAGE
LOAD6: MOVE T1,[.VPAG0+PAGSIZ+40,,.VPAG0+40] ;SETUP TO BLT 40-777
BLT T1,.VPAG0+PAGSIZ-1 ;MOVE THEM TO WHERE THEY BELONG
HRRZS P4 ;CLEAR FLAG
SUBI P2,PAGSIZ/BLKSIZ ;COMPENSATE FOR WHAT WE READ
JUMPG P2,LOAD4 ;DO THE REST IF MORE
LOAD7: AOBJN P1,.+1 ;SKIP PAST FIRST OF 2 WORDS
AOBJN P1,LOAD1 ;AND DO NEXT DESCRIPTOR
JRST CPOPJ1 ;GIVE SKIP RETURN
SUBTTL FILE SEARCH SUBROUTINES ;⊗ FNDMON
;ROUTINE TO FIND THE FILE CONTAINING THE MONITOR SPECIFIED IN THE
;FILESPEC AREA, READ THE EXE DIRECTORY INTO BUF AND SETUP TO READ
;THE FILE.
;CALL: PUSHJ P,FNDMON
;RETURN+1 IF FAILED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL WITH
; P1/AOBJN POINTER TO EXE DIRECTORY DESCRIPTORS
;DESTROYS P3-P4
FNDMON: PUSHJ P,FNDFIL ;FIND THE FILE
POPJ P, ;FILE NOT FOUND
PUSHJ P,REDBUF ;READ 1ST BLOCK OF EXE DIRECTORY
POPJ P, ;FAILED
HLRZ T1,BUF ;GET CODE
HRRZ P1,BUF ;AND LENGTH OF DIRECTORY
CAIN T1,SV.DIR ;THIS AN EXE FILE?
CAILE P1,BLKSIZ-1 ;AND NOT TOO LONG?
JRST BDFERR ;NO, BAD DIRECTORY FORMAT
MOVNI P1,-1(P1) ;BUILD -VE COUNT FOR AOBJN POINTER
HRLI P1,BUF+1 ;AND FIRST WORD
MOVSS P1 ;MAKE IT AN AOBJN POINTER TO BUF
JRST CPOPJ1 ;GIVE SKIP RETURN
;ROUTINE TO FIND A FILE AND SETUP ITS RIB IN RIB. CALL WITH ;⊗ FNDFIL FNDFI1 FNDFI2
;FILESPEC AREA SETUP.
;CALL: PUSHJ P,FNDFIL
;RETURN+1 IF NOT FOUND OR READ ERROR ON DIRECTORY WITH CODE IN T1
;RETURN+2 IF FILE FOUND
;DESTROYS P3-P4
FNDFIL: TLZ S,(FL.FFL) ;HAVEN'T FOUND FILE YET
PUSHJ P,SAVE2 ;SAVE P1-P2
PUSHJ P,FNDMFD ;FIND THE MFD
JRST SNTERR ;FAILED
MOVEI P1,0 ;SETUP LOOP POINTER TO PTHBLK
FNDFI1: SKIPN P3,PTHBLK(P1) ;GET NEXT UFD/SFD FROM PATH BLOCK
MOVE P3,FILNAM ;FOUND END, USE FILENAME
MOVEI P4,'UFD' ;ASSUME EXTENSION IS UFD
JUMPE P1,FNDFI2 ;GO IF CORRECT
MOVEI P4,'SFD' ;ASSUME SFD
SKIPN PTHBLK(P1) ;DONE WITH PATH BLOCK?
HLRZ P4,EXT ;YES, USE REAL EXTENSION
FNDFI2: PUSHJ P,SRCHFD ;SEARCH THE DIRECTORY
JRST FNTERR ;FILE NOT FOUND
PUSH P,T2 ;SAVE BLOCK IN UNIT OF RIB
PUSHJ P,FNDLUN ;FIND SPECIFIED UNIT
JRST [POP P,(P) ;FLUSH STACK
JRST SNTERR] ;GIVE ERROR CODE AND RETURN
POP P,F ;RESTORE BLOCK OF RIB
PUSHJ P,REDRBP ;READ THE RIB OF THE FILE
JRST FNTERR ;FAILED
SKIPE PTHBLK(P1) ;FOUND UFD, ALL SFD'S AND FILE?
AOJA P1,FNDFI1 ;NO, TRY NEXT LEVEL
TLO S,(FL.FFL) ;INDICATE THAT WE FOUND THE FILE
JRST CPOPJ1 ;GIVE SKIP RETURN, RIB SETUP
;ROUTINE TO FIND THE MFD FOR A STRUCTURE. CALL WITH DEV CONTAINING ;⊗ FNDMFD FNDMF1 SRCHFD SRCHF1 SRCHF2
;THE STRUCTURE NAME.
;CALL: PUSHJ P,FNDMFD
;RETURN+1 IF FAILED
;RETURN+2 IF FOUND WITH MFD RIB IN RIB
;DESTOYS P3-P4
FNDMFD: SETZM LUNPOS ;FIND UNIT ZERO OF STRUCTURE
PUSHJ P,FNDUNI ;FIND IT
POPJ P, ;FAILED, GIVE UP
MOVE T1,HOM+HOMMFD ;GET BLOCK IN STR CONTAINING MFD RIB
MOVE T2,HOM+HOMBSC ;GET BLOCKS/SUPERCLUSTER
IMUL T2,HOM+HOMSCU ;TIME SUPERCLUSTERS/UNIT
IDIV T1,T2 ;T1=UNIT, T2=BLOCK IN UNIT OF RIB
PUSH P,T2 ;SAVE BLOCK NUMBER
JUMPE T1,FNDMF1 ;GO IF ON UNIT ZERO
MOVEM T1,LUNPOS ;STORE UNIT
PUSHJ P,FNDUNI ;FIND UNIT
JRST TPOPJ ;FAILED
FNDMF1: POP P,F ;RESTORE BLOCK IN UNIT
MOVE P3,[1,,1] ;FILENAME IS [1,,1]
MOVEI P4,'UFD' ;EXTENSION IS UFD
PJRST REDRBP ;READ RIB OF MFD AND RETURN
;ROUTINE TO SEARCH A UFD OR SFD FOR A FILE. CALL WITH RIB SETUP
;IN RIB.
;CALL:
; P3/FILENAME, P4/0,,EXTENSION
; PUSHJ P,SRCHFD
;RETURN+1 IF FILE NOT FOUND
;RETURN+2 IF FOUND
;RETURNS T1=UNIT IN STR, T2=BLOCK IN UNIT OF RIB FOR FILE.
SRCHFD: PUSHJ P,REDBUF ;READ THE NEXT BLOCK OF THE DIRECTORY
POPJ P, ;EOF OR READ ERROR
MOVSI T1,-BLKSIZ ;BUILD AOBJN POINTER TO BLOCK
SRCHF1: HLRZ T2,BUF+1(T1) ;GET EXTENSION
CAMN P3,BUF(T1) ;FILENAMES MATCH?
CAME P4,T2 ;YES, EXTENSIONS MATCH?
AOBJN T1,.+2 ;NO, INCREMENT PAST FILENAME
JRST SRCHF2 ;YES
AOBJN T1,SRCHF1 ;LOOP FOR ALL OF THIS BLOCK
JRST SRCHFD ;TRY NEXT BLOCK
SRCHF2: HRRZ T1,BUF+1(T1) ;GET CFP FROM DIRECTORY
IDIV T1,HOM+HOMSCU ;T1=UNIT, T2=SUPERCLUSTER IN UNIT
IMUL T2,HOM+HOMBSC ;T2=BLOCK IN UNIT
JRST CPOPJ1 ;GIVE SKIP RETURN
SUBTTL BLOCK READ/WRITE SUBROUTINES ;⊗ WRTRIB WRTBUF REDBUF
;ROUTINE TO WRITE BUF/RIB TO THE OUTPUT FILE. CALL WITH RIB OF FILE
;SETUP.
;CALL: PUSHJ P,WRTBUF -OR- PUSHJ P,WRTRIB
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL
WRTRIB: MOVEI R,RIB ;POINT TO RIB
AOS SAVSIZ ;COMPENSATE FOR SELBLK DECREMENTING SAVSIZ
TLZA S,(FL.RIB) ;FORCE SELBLK TO WRITE THE RIB
WRTBUF: MOVEI R,BUF ;POINT TO BUF
MOVEI T1,1 ;NUMBER OF BLOCKS IS 1
PUSHJ P,SELBLK ;SETUP TO DO THAT MANY
JRST EOFERR ;FILE MUST BE REALLY SCREWED UP
JUMPN T1,EOFERR ;DITTO
PUSHJ P,VRTWRT ;WRITE THE BLOCK
JRST IOFERR ;WRITE ERROR
JRST CPOPJ1 ;GIVE SKIP RETURN
;ROUTINE TO READ ONE BLOCK FROM THE INPUT FILE INTO BUF. CALL WITH
;RIB OF FILE SETUP.
;CALL: PUSHJ P,REDBUF
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL
REDBUF: MOVEI R,BUF ;POINT TO BUF
MOVEI T1,1 ;NUMBER OF BLOCKS IS 1
PUSHJ P,SELBLK ;SETUP TO READ
JRST EOFERR ;HIT EOF
JUMPN T1,EOFERR ;DITTO
PUSHJ P,VRTRED ;READ THE BLOCK
JRST IOFERR ;READ ERROR
JRST CPOPJ1 ;GIVE SKIP RETURN
;ROUTINE TO POSITION AN EXE FILE SO THAT THE NEXT READ WILL READ ;⊗ POSFIL REDBLK
;THE BLOCKS THAT WE WANT.
;CALL:
; P4/DESIRED BLOCK IN FILE
; PUSHJ P,POSFIL
;RETURN+1 IF EOF ENCOUNTERED WITH ERROR CODE IN T1
;RETURN+2 WITH FILE POSITIONED CORRECTLY
POSFIL: CAMN P4,BLKNUM ;AT THE RIGHT BLOCK IN THE FILE NOW?
JRST CPOPJ1 ;YES, GIVE SKIP RETURN
MOVEI T1,1 ;DO ONE BLOCK
PUSHJ P,SELBLK ;USETI .+1
JRST EOFERR ;CANNOT HAVE EOF HERE
JRST POSFIL ;TRY AGAIN
;ROUTINE TO READ ONE OR MORE BLOCKS FROM AN EXE FILE.
;CALL: P2/NUMBER OF BLOCKS TO READ
; P3/CORE ADDRESS OF WHERE TO READ FIRST BLOCK
; P4/FILE BLOCK NUMBER OF FIRST BLOCK
; PUSHJ P,REDBLK
;RETURN+1 IF ERROR WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL WITH P3 AND P4 UPDATED TO REFLECT THE TRANSFER
REDBLK: JUMPLE P2,CPOPJ1 ;READ ALL BLOCKS YET?
MOVE T1,P2 ;NO, GET NUMBER OF BLOCKS TO TRANSFER
PUSHJ P,SELBLK ;SETUP TO DO THAT MANY
JRST EOFERR ;CAN'T HAVE EOF
MOVE R,P3 ;PUT CORE ADDRESS IN R
MOVE P2,T1 ;COPY BLOCKS WE COULDN'T DO FOR NEXT TIME
ADD P4,M ;INCREMENT FILE BLOCK NUMBER
MOVE T1,M ;GET NUMBER OF BLOCKS TO DO
LSH T1,B2WLSH ;CONVERT TO WORDS
ADD P3,T1 ;UPDATE CORE ADDRESS
PUSHJ P,@REDTAB(W) ;READ THE SPECIFIED BLOCKS
JRST IOFERR ;I/O ERROR
JRST REDBLK ;CONTINUE FOR ALL
;ROUTINE TO FIND A UNIT AND READ IT'S HOM BLOCK. CALL WITH LUNPOS ;⊗ FNDLUN FNDUNI FNDUN1 FNDUN2 FNDUN3
;CONTAINING THE LOGICAL UNIT NUMBER AND DEV CONTAINING THE DEVICE
;NAME.
;CALL:
; T1/LOGICAL UNIT IN STRUCTURE
; PUSHJ P,FNDLUN
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM
FNDLUN: EXCH T1,LUNPOS ;STORE UNIT, GET CURRENT
CAMN T1,LUNPOS ;SAME AS CURRENT ONE?
JRST CPOPJ1 ;YES, ALREADY THERE
;; PJRST FNDUNI ;FALL INTO FNDUNI
;ROUTINE TO FIND A UNIT BY EXHAUSTIVE SEARCH. CALL WITH LUNPOS
;CONTAINING THE LOGICAL UNIT NUMBER IN THE STRUCTURE, DEV CONTAINING
;THE STRUCTURE NAME AND SDLPOS CONTAINING THE POSITION IN THE SYSTEM
;DUMP LIST.
;CALL: PUSHJ P,FNDUNI
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM
FNDUNI: MOVSI J,-DVCTBL ;AOBJN POINTER TO DEVICE CODE TABLE
FNDUN1: MOVSI U,-MAXUNI ;AOBJN POINTER FOR EACH UNIT
FNDUN2: HLRZ W,DVCTAB(J) ;SETUP TYPE OFFSET
PUSHJ P,SETIOT ;SETUP I/O INSTRUCTIONS
PUSHJ P,REDHOM ;READ HOM BLOCK FOR UNIT
JRST FNDUN3 ;FAILED OR BAD
MOVE T1,HOM+HOMLUN ;GET LOGICAL UNIT NUMBER OF THIS STR
MOVE T2,HOM+HOMSNM ;GET STR NAME
CAMN T1,LUNPOS ;UNIT NUMBER MATCH?
CAME T2,DEV ;YES, DOES IT?
JRST FNDUN3 ;NO
JRST CPOPJ1 ;YES, GIVE SKIP RETURN
FNDUN3: AOBJN U,FNDUN2 ;LOOP FOR NEXT UNIT
AOBJN J,FNDUN1 ;LOOP FOR NEXT CONTROLLER
POPJ P, ;ERROR RETURN
;ROUTINE TO READ A HOM BLOCK. ;⊗ REDHOM REDHO1 REDHO2
;CALL:
; U/PHYSICAL UNIT NUMBER
; J/OFFSET INTO DEVICE CODE TABLE
; W/OFFSET INTO TYPE TABLES
; PUSHJ P,REDHOM
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL WITH HOM BLOCK IN HOM
REDHOM: MOVEI R,HOM ;ADDRESS OF WHERE TO PUT IT
MOVEI F,LBNHOM ;ADDRESS OF FIRST HOM BLOCK ON UNIT
MOVEI M,1 ;READ 1 BLOCK
REDHO1: PUSHJ P,VRTRED ;READ THE BLOCK
JRST REDHO2 ;FAILED, TRY SECOND
MOVS T1,HOM+HOMNAM ;GET FIRST WORD OF BLOCK
MOVE T2,HOM+HOMCOD ;GET WORD CONTAINING UNLIKELY CODE
CAIN T1,'HOM' ;NAME MUST BE HOM
CAIE T2,CODHOM ;AND MUST MATCH UNLIKELY CODE
JRST REDHO2 ;ONE FAILED
CAMN F,HOM+HOMSLF ;SELF POINTER MUST MATCH
SKIPE HOM+HOMREF ;AND MUST NOT NEED REFRESHING
JRST REDHO2 ;FAILED
MOVEI T1,T4 ;SETUP HOMCLP AND
HRRM T1,HOM+HOMCLP ; HOMCNP TO POINT
HRRM T1,HOM+HOMCNP ; TO T4
JRST CPOPJ1 ;GIVE SKIP RETURN
REDHO2: CAIN F,LBNHOM ;DOING FIRST HOM BLOCK?
POPJ P, ;NO, GIVE FAIL RETURN
MOVEI F,LB2HOM ;GET ADDRESS OF 2ND
JRST REDHO1 ;AND TRY THAT ONE
;ROUTINE TO READ A RIB. ;⊗ REDRIB REDRBP
;CALL:
; U/PHYSICAL UNIT NUMBER
; J/OFFSET INTO DEVICE CODE TABLE
; W/OFFSET INTO TYPE TABLES
; F/BLOCK IN UNIT
; PUSHJ P,REDRIB
;RETURN+1 IF READ OR RIB ERROR
;RETURN+2 IF SUCCESSFUL WITH RIB IN RIB
;CALL REDRBP IF FILENAME AND EXTENSION ALREADY IN P3,P4
;DESTROYS P3-P4
REDRIB: MOVE P3,FILNAM ;GET FILENAME
HLRZ P4,EXT ;AND EXT
REDRBP: MOVEI R,RIB ;ADDRESS OF WHERE TO READ IT
MOVEI M,1 ;READ 1 BLOCK
PUSHJ P,VRTRED ;READ THE BLOCK
POPJ P, ;FAILED
MOVE T1,RIB+RIBCOD ;GET WORD CONTAINING UNLIKELY CODE
CAIN T1,CODRIB ;MUST MATCH
SKIPL T1,RIB+RIBFIR ;POINTER MUST BE NEGATIVE
POPJ P, ;FAILED
MOVEM T1,SAVFIR ;SAVE FOR SELBLK
MOVE T1,RIB+RIBNAM ;GET FILENAME FROM RIB
CAMN T1,P3 ;MATCH WITH WHAT WE WANT?
CAME F,RIB+RIBSLF ;SELF POINTER MUST MATCH
POPJ P, ;ELSE ERROR
HLRZ T1,RIB+RIBEXT ;GET EXTENSION FROM RIB
MOVE T2,PTHBLK ;GET PPN FROM PATH BLOCK
CAIN P4,'UFD' ;READING A UFD?
MOVE T2,[1,,1] ;YES, PPN IS 1,1
CAMN T1,P4 ;EXTENSION MATCH?
CAME T2,RIB+RIBPPN ; ALONG WITH PPN?
POPJ P, ;NO, ERROR
TLO S,(FL.RIB) ;TELL SELBLK THAT FIRST BLOCK IS A RIB
SETOM BLKCNT ;AND NO BLOCKS LEFT IN GROUP
MOVE T1,RIB+RIBSIZ ;GET RIBSIZ FROM RIB
ADDI T1,BLKSIZ-1 ;ROUND UP TO A BLOCK
LSH T1,W2BLSH ;CONVERT TO BLOCKS
TLZE S,(FL.EXR) ;READING EXTENDED RIB?
JRST CPOPJ1 ;YES, GIVE SKIP RETURN
MOVEM T1,SAVSIZ ;NO, SAVE SIZE FOR SELBLK
SETZM BLKNUM ;AND ZERO RELATIVE BLOCK IN FILE
JRST CPOPJ1 ;AND GIVE SKIP RETURN
;ROUTINE TO SETUP A TRANSFER TO/FROM DISK. ;⊗ SELBLK SELBL1 SELBL2 SELBL3
;CALL:
; T1/NUMBER OF BLOCKS DESIRED TO TRANSFER
; PUSHJ P,SELBLK
;RETURN+1 IF EOF DETECTED
;RETURN+2 IF SOME TRANSFER IS POSSIBLE
;RETURNS M/NUMBER OF BLOCKS POSSIBLE, T1/NUMBER OF BLOCKS IN REQUEST
; THAT COULDN'T BE TRANSFERED, F/BLOCK ON UNIT OF FIRST BLOCK.
;PRESERVES P3-P4
SELBLK: TLNN S,(FL.RIB) ;WANT TO SKIP FIRST RIB BLOCK?
JRST SELBL1 ;NO
PUSHJ P,SAVE2 ;SAVE P1-P2
MOVE P1,T1 ;SAVE REQUESTED TRANSFER IN P1
MOVEI T1,1 ;AND MAKE IT LOOK LIKE 1 BLOCK
SELBL1: SKIPLE BLKCNT ;AND MORE BLOCKS LEFT IN GROUP?
JRST SELBL4 ;YES, USE THEM
SELBL2: SKIPL T2,SAVFIR ;RUN OUT OF POINTERS?
JRST SELBL5 ;YES, CHECK FOR EXTENDED RIBS
MOVE T4,RIB(T2) ;GET NEXT POINTER
AOBJN T2,.+1 ;INCREMENT POINTER TO POINTERS
MOVEM T2,SAVFIR ;STORE POINTER BACK
LDB T2,HOM+HOMCNP ;GET CLUSTER COUNT FROM THIS POINTER
JUMPN T2,SELBL3 ;GO IF NON-ZERO
TRZN T4,RIPNUB ;UNIT CHANGE POINTER?
POPJ P, ;NO, THAT'S AN EOF POINTER
PUSH P,T1 ;SAVE ARGUMENT
MOVE T1,T4 ;COPY NEW UNIT NUMBER
PUSHJ P,FNDLUN ;FIND IT AND SETUP HOM BLOCK
JRST TPOPJ ;NOT THERE, SIMULATE EOF
POP P,T1 ;RESTORE ARGUMENT
JRST SELBL2 ;TRY WITH NEXT POINTER
SELBL3: IMUL T2,HOM+HOMBPC ;COMPUTE NUMBER OF BLOCKS IN GROUP
SKIPL SAVFIR ;DOING LAST POINTER IN THIS RIB?
SUBI T2,1 ;YES, DON'T OVERWRITE SPARE RIB
TLNE S,(FL.RIB) ;SKIPPING A RIB?
AOS SAVSIZ ;YES, FILE IS 1 MORE BLOCK LONG
CAMLE T2,SAVSIZ ;MORE THAN AMOUNT REMAINING IN FILE?
MOVE T2,SAVSIZ ;YES, USE THAT
MOVEM T2,BLKCNT ;STORE IT
LDB T2,HOM+HOMCLP ;GET CLUSTER ADDRESS OF 1ST CLUSTER IN GROUP
IMUL T2,HOM+HOMBPC ;COMPUTE BLOCK ADDRESS
MOVEM T2,BLKADR ;STORE ADDRESS OF BLOCK
;CONTINUED ON THE NEXT PAGE
SELBL4: MOVN M,T1 ;GET -VE NUMBER OF BLOCKS IN REQUEST ;⊗ SELBL4 SELBL5 SELBL6
SUB T1,BLKCNT ;SUBTRACT AMOUNT LEFT IN GROUP
SKIPLE T1 ;REQUEST LARGER THAN AMOUNT WE HAVE?
MOVN M,BLKCNT ;YES, USE WHAT WE HAVE
ADDM M,BLKCNT ;DECREASE BLKCNT BY APPROPRIATE AMOUNT
ADDM M,SAVSIZ ; AND SIZE OF FILE
MOVNS M ;SET M TO AMOUNT TO TRANSFER
MOVE F,BLKADR ;START AT THIS BLOCK
ADDM M,BLKADR ;INCREMENT BLOCK ADDRESS FOR NEXT CALL
TLNN S,(FL.RIB) ;SKIPING A RIB?
ADDM M,BLKNUM ;NO, UPDATE RELATIVE FILE BLOCK
SKIPGE T1 ;CAN WE DO THE WHOLE REQUEST?
MOVEI T1,0 ;YES, RETURN ZERO AS REMAINDER
TLZN S,(FL.RIB) ;SKIPPING 1 BLOCK FOR RIB?
JRST CPOPJ1 ;NO, RETURN TO CALLER
MOVE T1,P1 ;RESTORE ORIGINAL REQUEST
JRST SELBL1 ;AND DO THE REAL REQUEST
SELBL5: SKIPN RIB+RIBXRA ;EXTENDED RIB POINTER?
POPJ P, ;NO, GIVE EOF RETURN
PUSH P,T1 ;SAVE ARGUMENT
PUSH P,P3 ;AND QUASI-PRESERVED REGISTERS
PUSH P,P4 ;SMASHED BY REDRIB
LDB T1,DEYRBU ;GET UNIT ON WHICH NEXT RIB EXISTS
PUSHJ P,FNDLUN ;FIND UNIT, SETUP HOM BLOCK
JRST SELBL6 ;FAILED GIVE EOF RETURN
LDB F,DEYRBA ;GET CLUSTER ADDRESS ON THAT UNIT
IMUL F,HOM+HOMBPC ;CONVERT TO BLOCK ADDRESS
TLO S,(FL.EXR) ;DON'T CHANGE SAVSIZ FOR EXTENDED RIBS
PUSHJ P,REDRIB ;READ NEW RIB
JRST SELBL6 ;FAILED, GIVE EOF RETURN
POP P,P4 ;RESTORE P4 AND
POP P,P3 ; P3
POP P,T1 ;RESTORE ARGUMENT
JRST SELBLK ;AND TRY NEW POINTER FROM THIS RIB
SELBL6: TLZ S,(FL.EXR) ;MAKE SURE THIS FLAG IS OFF
IFN FTKL10!FTKS10,<
ADJSP P,-3 ;BRING STACK INTO SYNC
>
IFN FTKI10,<
SUB P,[3,,3] ;HARDER FOR THE KI10
>
POPJ P, ;AND GIVE NON-SKIP RETURN
SUBTTL SUPPORT SUBROUTINES ;⊗ CLRBUF SETIOT ERRTAB SNTERR FNTERR UPDERR EOFERR IOFERR BDFERR MCCERR NSSERR ERRTBL ALLERR
;ROUTINE TO CLEAR BUF.
;CALL: PUSHJ P,CLRBUF
;RETURN+1 ALWAYS
CLRBUF: SETZM BUF ;CLEAR FIRST WORD
MOVE T1,[BUF,,BUF+1] ;SETUP FOR BLT
BLT T1,BUF+BLKSIZ-1 ;CLEAR IT ALL
POPJ P, ;RETURN
;ROUTINE TO STORE A DEVICE CODE IN ALL I/O INSTRUCTIONS.
;CALL:
; J/OFFSET INTO DEVICE CODE TABLE
; PUSHJ P,SETIOT
;RETURN+1 ALWAYS
SETIOT:
IFN FTKL10!FTKI10,<
HRRZ T1,DVCTAB(J) ;GET DEVICE CODE
MOVSI T2,-IOTTBL ;BUILD AOBJN POINTER TO IOTTAB
DPB T1,[POINT 7,IOTTAB(T2),9] ;STORE DEVICE CODE IN INSTN.
AOBJN T2,.-1 ;DO THEM ALL
>
POPJ P, ;RETURN
;RETURN POINTS TO SET T1 TO AN ERROR CODE AND NON-SKIP RETURN
ERRTAB:
SNTERR: PJSP T1,ALLERR ;STRUCTURE NOT FOUND
FNTERR: PJSP T1,ALLERR ;FILE NOT FOUND
UPDERR: PJSP T1,ALLERR ;UNPROCESSED DUMP
EOFERR: PJSP T1,ALLERR ;UNEXPECTED EOF
IOFERR: PJSP T1,ALLERR ;I/O ERROR
BDFERR: PJSP T1,ALLERR ;BAD DIRECTORY FORMAT
MCCERR: PJSP T1,ALLERR ;MEM CONFIG TOO COMPLICATED
NSSERR: PJSP T1,ALLERR ;NOT SYSTEM SLEEP DUMP
ERRTBL==.-ERRTAB
ALLERR: SUBI T1,ERRTAB+1 ;COMPUTE ERROR CODE
TLZ T1,-1 ;CLEAR LH JUNK
POPJ P, ;RETURN
;ROUTINE TO READ DATA INTO A VIRTUAL ADDRESS. ;⊗ VRTRED VRTWRT MAPADR
;CALL:
; R/VIRTUAL ADDRESS
; M/NUMBER OF BLOCKS TO TRANSFER
; F/BLOCK ON UNIT
; U/PHYSICAL UNIT
; W/OFFSET INTO TYPE TABLE
; J/OFFSET INTO DEVICE CODE TABLE
; PUSHJ P,VRTRED
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL
VRTRED: PUSHJ P,MAPADR ;CONVERT VIRTUAL TO PHYSICAL ADDRESS
PJRST @REDTAB(W) ;DO THE TRANSFER
;ROUTINE TO WRITE DATA FROM A VIRTUAL ADDRESS. CALL WITH SAME ARGUMENTS
;AS VRTRED.
;CALL: PUSHJ P,VRTWRT
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL
VRTWRT: PUSHJ P,MAPADR ;CONVERT VIRTUAL TO PHYSICAL ADDRESS
PJRST @WRTTAB(W) ;DO THE TRANSFER
;ROUTINE TO CONVERT A VIRTUAL ADDRESS TO A PHYSICAL ADDRESS.
;CALL:
; R/VIRTUAL ADDRESS
; PUSHJ P,MAPADR
;RETURN+1 ALWAYS WITH PHYSICAL ADDRESS IN R
MAPADR:
IFN FTKI10,<
PUSH P,R ;SAVE VIRTUAL ADDRESS
ANDI R,PAGSIZ-1 ;KEEP ONLY OFFSET IN PAGE
EXCH R,0(P) ;STORE THAT, GET FULL ADDRESS
>
MAP R,(R) ;CONVERT TO PHYSICAL ADDRESS
IFN FTKI10,<
LSH R,P2WLSH ;CONVERT PAGE NUMBER TO ADDRESS
IOR R,0(P) ;INCLUDE OFFSET IN PAGE
POP P,(P) ;FLUSH STACK
TLZ R,(↑-<PG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
IFN FTKL10,<
TLZ R,(↑-<LG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
IFN FTKS10,<
TLZ R,(↑-<SG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
POPJ P, ;AND RETURN
;ROUTINE TO SAVE P1 AND P2 AND CALL THE CALLER AS A COROUTINE ;⊗ SAVE2 SAVFR
;WHICH RESTORES P1 AND P2 WHEN THE CALLER RETURNS.
;CALL: PUSHJ P,SAVE2
;RETURN+1 ALWAYS
SAVE2: EXCH P1,(P) ;GET RETURN, SAVE P1
PUSH P,P2 ;SAVE P2
MOVEM P1,1(P) ;SAVE RETURN
MOVE P1,-1(P) ;RESTORE P1
PUSHJ P,@1(P) ;CALL CALLER
CAIA ;NON SKIP
AOS -2(P) ;SKIP RET
POP P,P2 ;RESTORE P2
POP P,P1 ;RESTORE P1
POPJ P, ;RETURN
;ROUTINE TO SAVE F AND R AND CALL THE CALLER AS A COROUTINE
;WHICH RESTORES F AND R WHEN THE CALLER RETURNS.
;CALL: PUSHJ P,SAVFR
;RETURN+1 ALWAYS
SAVFR: EXCH F,(P) ;GET RETURN, SAVE F
PUSH P,R ;SAVE R
MOVEM F,1(P) ;SAVE RETURN
MOVE F,-1(P) ;RESTORE F
PUSHJ P,@1(P) ;CALL CALLER
CAIA ;NON SKIP
AOS -2(P) ;SKIP RET
POP P,R ;RESTORE R
POP P,F ;RESTORE F
POPJ P, ;RETURN
SUBTTL MOVE BOOT TO TOP OF MEMORY AND ZERO CORE ;⊗ MOVBTS
;ROUTINE TO MOVE BOOT TO THE TOP OF CORE SO THAT A NEW MONITOR
;CAN BE LOADED. ALSO CALLED ON A REBOOT REQUEST TO MOVE BOOT TO THE
;COMMUNICATION REGION SPECIFIED BY MBTCOM IN THE DUMP.
;CALL:
; T2/PHYSICAL PAGE NUMBER OF WHERE TO MOVE BOOT
; PUSHJ P,MOVBTS
;RETURN+1 ALWAYS
MOVBTS: LSH T2,P2WLSH ;CONVERT PAGE NUMBER TO ADDRESS
CAMN T2,EPTADR ;MOVING TO THE SAME SPOT?
POPJ P, ;YES, JUST RETURN
MOVEM T2,EPTADR ;STORE PHYSICAL ADDRESS OF NEW EPT
LSH T2,W2PLSH ;CONVERT BACK TO PAGE NUMBER
MOVEI T1,PM.ACC+PM.WRT(T2) ;GET MAP SLOT ENTRY FOR THIS PAGE
HRLI T1,-BOOPGS ;MAKE IT AN AOBJN POINTER
MOVE T3,[POINT 18,EPT+.MMOVE] ;GET BYTE POINTER TO MAP SLOT
IDPB T1,T3 ;MAKE ENOUGH PAGE ADDRESSABLE TO MOVE BOOT
AOBJN T1,.-1 ;DO THEM ALL
MOVE T1,CPEBR ;GET CURRENT MAPPING
XCT CHGEBR ;CAUSE THE PAGE TABLE TO BE FLUSHED
MOVE T3,[.VBOOT,,.VMOVE] ;SETUP BLT WORD TO MOVE IT ALL
BLT T3,.VMOVE+BOOLEN-1 ;DO SO
MOVEI T3,PM.ACC+PM.WRT(T2) ;GET MAP SLOT ENTRY
HRLI T3,-BOOPGS ;MAKE ANOTHER AOBJN POINTER
MOVE T4,[POINT 18,.VMOVE+.MBOOT] ;POINT TO MAP
IDPB T3,T4 ;SLOTS IN NEW MAP TO MAKE US
AOBJN T3,.-1 ;ADDRESSABLE
IFN FTKI10,<
TRZ T1,PG.EPT ;CLEAR OLD PAGE NUMBER
MOVSI T4,<(PG.LUB)>(T2) ;GET ARGUMENT TO CHANGE UBR ALSO
>
IFN FTKL10,<
TRZ T1,LG.EPT ;CLEAR OLD PAGE NUMBER
MOVEI T4,LG.IAM(T2) ;GET ARGUMENT TO CHANGE
HRLI T4,(LG.LAB!LG.LPC!LG.LUB) ; UBR ALSO
>
IFN FTKS10,<
TRZ T1,SG.EPT ;CLEAR OLD PAGE NUMBER
MOVEI T4,(T2) ;GET ARGUMENT TO CHANGE
HRLI T4,(SG.LAB!SG.LUB) ; UBR ALSO
>
IORI T1,(T2) ;INSERT NEW EPT PAGE NUMBER
MOVEM T1,.VMOVE+CPEBR-.VBOOT ;STORE NEW MAPPING
XCT CHGEBR ;CONTINUE EXECUTION AT TOP OF CORE
XCT CHGUBR ;CHANGE UPT ALSO
;HERE AFTER HAVING MOVED BOOT TO THE TOP OF CORE TO ZERO ALL OTHER ;⊗ MOVBT1 MOVBT2
;PAGES IN MEMORY. ONLY DO THIS ONCE.
TLOE S,(FL.ZER) ;ALREADY DONE THIS ONCE?
POPJ P, ;YES, RETURN NOW
MOVE T4,T2 ;PUT EPT PAGE NUMBER IN T4
MOVE T2,MEMPSZ ;GET NUMBER OF PAGES DESCRIBED BY NXMTAB
SUBI T2,1 ;CALCULATE THE HIGHEST PAGE # IN CORE
MOVBT1: CAIL T2,(T4) ;IS THIS PAGE
CAILE T2,BOOPGS-1(T4) ; OCCUPIED BY BOOT?
PUSHJ P,CHKNXM ;NO, DOES IT EXIST?
JRST MOVBT2 ;NO, TRY NEXT
MOVEI T1,PM.ACC+PM.WRT(T2) ;GET NEXT PAGE TO ZERO
HRLM T1,EPT+.MZERO ;STORE IN MAP SLOT TO USE
IFN FTKL10!FTKS10,<
CLRPT .VZERO ;FLUSH PAGE TABLE FOR THAT PAGE
>
IFN FTKI10,<
MOVE T1,CPEBR ;GET EPT MAPPING
XCT CHGEBR ;CAUSE PAGE TABLE TO BE FLUSHED
>
MOVE T3,[.VZERO,,.VZERO+1] ;SETUP BLT POINTER
SKIPN T2 ;ABOUT TO DO PAGE 0?
IFN FTKI10,<
ADD T3,[40,,40] ;YES, DON'T CLEAR 0-37
>
IFN FTKL10!FTKS10,<
ADJSP T3,40 ;YES, DON'T CLEAR 0-37
>
SETZM -1(T3) ;CLEAR FIRST WORD OF PAGE
BLT T3,.VZERO+PAGSIZ-1 ;DO IT ALL
MOVBT2: SOJGE T2,MOVBT1 ;LOOP IF MORE TO DO
POPJ P, ;RETURN
SUBTTL NXMTAB HANDLING ROUTINES ;⊗ FINDHI FINDH1 FINDH2 FNDPGS FNDPG1 FNDPG2
;ROUTINE TO FIND MBTPGS CONTIGUOUS PAGES STARTING AT THE TOP OF
;CORE SO THAT WE CAN MOVE BOOT THERE.
;CALL: PUSHJ P,FINDHI
;RETURN+1 ALWAYS WITH STARTING PAGE NUMBER IN T2
FINDHI: MOVE T2,MEMPSZ ;GET NUMBER OF PAGES IN CORE
FINDH1: MOVEI T1,BOOPGS ;NUMBER OF CONTIGUOUS PAGES WE NEED
FINDH2: SOS T2 ;DECREMENT PAGE NUMBER
PUSHJ P,CHKNXM ;DOES THIS PAGE EXIST?
JRST FINDH1 ;NO, RESET COUNT AND TRY AGAIN
SOJG T1,FINDH2 ;YES, DECREMENT PAGE AND CHECK IT
POPJ P, ;FOUND THEM, RETURN PAGE # IN T2
;ROUTINE TO FIND A CONTIGUOUS GROUP OF PAGES WHICH EXIST BY LOOKING
;THROUGH NXMTAB. I KNOW THAT THIS ISN'T PARTICULARLY FAST BUT I WAS
;IN A HURRY.
;CALL:
; P2/PAGE NUMBER OF WHERE TO START
; PUSHJ P,FNDPGS
;RETURN+1 ALWAYS
;RETURNS P1=COUNT OF PAGES
; P2=STARTING PAGE NUMBER
FNDPGS: MOVEI P1,0 ;START WITH NO PAGES FOUND
SOS P2 ;TAKE A RUNNING START AT THE LOOP
FNDPG1: AOS T2,P2 ;INCREMENT PAGE NUMBER, COPY TO T2
CAML T2,MEMPSZ ;OFF THE END OF MEMORY?
POPJ P, ;YES, RETURN WITH P1=0
PUSHJ P,CHKNXM ;DOES THAT PAGE EXIST?
JRST FNDPG1 ;NO, LOOP FOR NEXT
FNDPG2: CAMGE T2,MEMPSZ ;OFF THE END OF MEMORY?
PUSHJ P,CHKNXM ;NO, DOES THIS PAGE EXIST?
POPJ P, ;NO, RETURN
AOS P1 ;INCREMENT COUNT OF PAGES
AOJA T2,FNDPG2 ;INCREMENT PAGE NUMBER AND LOOP
;ROUTINE TO CHECK NXMTAB TO SEE IF A PAGE EXISTS. ;⊗ CHKNXM SUNXMT SUNXM1 SUNXM2
;CALL:
; T2/PHYSICAL PAGE NUMBER
; PUSHJ P,CHKNXM
;RETURN+1 IF MARKED AS NXM
;RETURN+2 IF NOT
;PRESERVES T2, DESTROYS T3
CHKNXM: PUSH P,T2 ;SAVE PAGE NUMBER
IDIVI T2,↑D36 ;DIVIDE BY THE NUMBER OF BITS PER WORD
MOVE T2,NXMTAB(T2) ;GET THE WORD CONTAINING THE BIT
LSH T2,(T3) ;SHIFT NXM BIT TO 1B0
SKIPL T2 ;MARKED AS A NXM?
AOS -1(P) ;NO, GIVE SKIP RETURN
POP P,T2 ;RESTORE T2
POPJ P, ;RETURN
;ROUTINE TO BUILD NXMTAB BY TOUCHING EVERY POSSIBLE PAGE IN MEMORY
;TO SEE IF IT EXISTS.
;CALL: PUSHJ P,SUNXMT
;RETURN+1 ALWAYS
SUNXMT: PUSHJ P,SAVE2 ;SAVE P1-P2
SETZM NXMTAB ;ZERO FIRST WORD OF NXMTAB
MOVE T1,[NXMTAB,,NXMTAB+1] ;GET BLT POINTER
BLT T1,NXMTBE ;ZERO IT ALL
IFN FTKL10!FTKS10,<
PUSH P,EPT+.LMPFN ;SAVE PAGE FAIL NEW PC
MOVEI T1,REFTRP ;NEED NEW PC SINCE NXM'S SOMETIMES
MOVEM T1,EPT+.LMPFN ; CAUSE AR/ARX PARITY ERRORS
>
MOVSI P1,-MAXPGS ;GET LOOP COUNT FOR ALL POSSIBLE PAGES
MOVEI P2,0 ;P2 WILL BE HIGHEST PAGE SEEN
MOVE T2,[POINT 1,NXMTAB] ;GET BYTE POINTER TO NXMTAB
MOVEI T3,1 ;AND A BIT TO USE
SUNXM1: IBP T2 ;STEP BYTE POINTER TO NEXT BIT
PUSHJ P,REFMEM ;TOUCH THAT PAGE
SKIPA P2,P1 ;EXISTS, MOVE NUMBER TO P2
DPB T3,T2 ;SET THE BIT FOR THIS PAGE
AOBJN P1,SUNXM1 ;LOOP FOR ALL PAGES
ADDI P2,1 ;P2:=NUMBER OF PAGES IN MEMORY
HRRZM P2,MEMPSZ ;STORE FOR LATER
SUNXM2: IDPB T3,T2 ;STORE 1'S IN THE REST
TLNE T2,(77B5) ; OF THE FINAL
JRST SUNXM2 ; WORD
IFN FTKL10!FTKS10,<
POP P,EPT+.LMPFN ;RESTORE OLD PAGE FAIL TRAP ADDRESS
>
CONO APR,CLRAPR ;CLEAR APR ERRORS
POPJ P, ;AND RETURN
;ROUTINE TO DETERMINE IF A PAGE EXISTS IN MEMORY BY TOUCHING ;⊗ REFMEM REFTRP
;THAT PAGE. NOTE THAT THE PAGE FAIL TRAP ADDRESS IN THE UPT HAS
;BEEN CHANGED TO POINT AT REFTRP BY THE CALLER.
;CALL:
; P1/PHYSICAL PAGE NUMBER
; PUSHJ P,REFMEM
;RETURN+1 IF PAGE EXISTS
;RETURN+2 IF PAGE DOES NOT EXIST
REFMEM: CONO APR,CLRAPR ;CLEAR APR ERRORS
MOVEI T1,PM.ACC!PM.WRT(P1) ;GET MAP ENTRY FOR PAGE
HRLM T1,EPT+.MZERO ;USE .VZERO AS TEMPORARY PAGE
IFN FTKL10!FTKS10,<
CLRPT .VZERO ;FLUSH THE PAGE TABLE FOR THAT PAGE
>
IFN FTKI10,<
MOVE T1,CPEBR ;GET CURRENT EPT MAPPING
XCT CHGEBR ;FLUSH THE PAGE TABLE
>
MOVES .VZERO ;TOUCH THE PAGE
REFTRP:
IFN FTKI10,<
CONSZ APR,IP.NXM ;SEE A NXM?
>
IFN FTKL10,<
CONSZ APR,LP.NXM ;SEE A NXM?
>
IFN FTKS10,<
CONSZ APR,SP.NXM ;SEE A NXM?
>
AOS 0(P) ;YES, GIVE SKIP RETURN
POPJ P, ;RETURN
SUBTTL TRAP HANDLING ;⊗ TRAP PFTRAP PFTRA1
;HERE ON A TRAP OTHER THAN A PAGE FAIL.
TRAP: MOVEI T1,[ASCIZ/?Trap other than page fail
MUUO = /]
PUSHJ P,PRMSG
MOVE T4,EPT+.UPMUO ;GET MUUO
PUSHJ P,PRHWD ;PRINT AS HALF WORDS
MOVEI T1,[ASCIZ/
MUUO PC = /]
PUSHJ P,PRMSG
MOVE T4,EPT+.UPMUP ;GET OLD PC WORD
PUSHJ P,PRHWD ;PRINT AS HALF WORDS
JRST PFTRA1 ;JOIN COMMON EXIT CODE
;HERE ON A PAGE FAIL TRAP
PFTRAP:
IFN FTKI10,<
EXP 0 ;JSR HERE ON A KI
>
MOVEI T1,[ASCIZ/?Page fail trap
PFW = /]
PUSHJ P,PRMSG ;PRINT ERROR MESSAGE
IFN FTKI10,<
MOVE T4,EPT+.UPEPF ;GET PAGE FAIL WORD
>
IFN FTKL10!FTKS10,<
MOVE T4,EPT+.LMPFW ;GET PAGE FAIL WORD
>
PUSHJ P,PRHWD ;PRINT AS HALF-WORDS
MOVEI T1,[ASCIZ/
PF PC = /]
PUSHJ P,PRMSG
IFN FTKI10,<
MOVE T4,PFTRAP ;GET PC OF FAILURE
>
IFN FTKL10!FTKS10,<
MOVE T4,EPT+.LMPFP ;GET PC OF FAILURE
>
PUSHJ P,PRHWD ;PRINT IT AS HALF WORDS
PFTRA1: PUSHJ P,PRTAPR ;PRINT APR STATUS
JRST RLDMON ;RESTART AT THE BEGINNING
;ROUTINE TO PRINT THE CONI APR AND RDERA (IF A KL10). ;⊗ PRTAPR
;CALL: PUSHJ P,PRTAPR
;RETURN+1 ALWAYS
PRTAPR: MOVEI T1,[ASCIZ/
CONI APR, = /]
PUSHJ P,PRMSG
CONI APR,T4 ;GET CONI APR
PUSHJ P,PRHWD ;PRINT AS HALF WORDS
IFN FTKL10,<
MOVEI T1,[ASCIZ/
RDERA = /]
PUSHJ P,PRMSG
RDERA T4 ;GET ERA
PUSHJ P,PRHWD ;PRINT AS HALF WORDS
>
PJRST PRCRLF ;END LINE AND RETURN
SUBTTL COMMAND PARSING ;⊗ PARSE PARSE1 PARSE2 PARSE3 CMDERR TRMTAB TRMTBL
;ROUTINE TO PARSE A COMMAND LINE.
;RETURNS WITH THE FILESPEC VARIABLE AND BITS IN S SETUP.
;CALL: PUSHJ P,PARSE
;RETURN+1 IF ERROR DETECTED AND MESSAGE ISSUED
;RETURN+2 IF NO ERRORS DETECTED
PARSE: SETZM FILSPC ;CLEAR FIRST WORD OF FILESPEC
MOVE T1,[FILSPC,,FILSPC+1] ;SETUP FOR BLT
BLT T1,FILSPE ;CLEAR IT ALL
TDZA S,[FX.CLR] ;CLEAR FLAG BITS AND GET FIRST ATOM
PARSE1: TDZA T1,T1 ;CLEAR ATOM, SKIP CALL TO GETSIX
PARSE2: PUSHJ P,GETSIX ;GET SIXBIT ATOM IN T1
MOVSI T2,-TRMTBL ;-VE LENGTH OF TERMINATING CHAR TABLE
PARSE3: HLRZ T4,TRMTAB(T2) ;GET NEXT POSSIBLE CHARACTER FROM TABLE
CAIE T4,(T3) ;MATCH WITH THE ONE WE SAW?
AOBJN T2,PARSE3 ;NO, LOOP
HRRZ T4,TRMTAB(T2) ;GET DISPATCH ADDRESS FOR ATOM
JUMPL T2,(T4) ;GO TO ROUTINE IF MATCH FOUND
CMDERR: MOVEI T1,[ASCIZ/%Syntax error
/]
PJRST PRMSG ;TELL OF ERROR AND RETURN
;TABLE OF LEGAL CHARACTERS TERMINATING COMMAND STRING ATOMS AND
;THE CORRESPONDING DISPATCH ADDRESSES. FORMAT IS:
; XWD CHAR,ADDRESS
TRMTAB: XWD ":",CMDDEV ;DEVICE SEEN
XWD ".",CMDFIL ;FILENAME SEEN
XWD "[",CMDPTH ;START OF PATCH SEEN
XWD "/",CMDSWT ;SWITCH SEEN
XWD .CHCRT,CMDEOL ;END OF LINE SEEN
TRMTBL==.-TRMTAB ;LENGTH OF TABLE
;HERE TO PROCESS DEVICE IN COMMAND STRING ;⊗ CMDDEV CMDFIL CMDPTH CMDPT1 CMDPT2
CMDDEV: TRON S,FR.DEV ;ALREADY HAVE A DEVICE?
SKIPN T1 ;NO, DEVICE NULL?
JRST CMDERR ;YES, ERROR
MOVEM T1,DEV ;STORE DEVICE
JRST PARSE2 ;AND GET NEXT ATOM
;HERE TO PROCESS FILENAME IN COMMAND STRING
CMDFIL: JSP T2,STOFIL ;STORE FILENAME AS NECESSARY
TROE S,FR.EXT ;FLAG AN EXTENSION SEEN
JRST CMDERR ;ERROR IF MORE THAN ONE
PUSHJ P,GETSIX ;GET EXTENSION
HLLZM T1,EXT ;STORE IT
JRST PARSE1 ;GET NEXT ATOM
;HERE TO PROCESS PATH SPEC IN COMMAND STRING
CMDPTH: JSP T2,STOFIL ;STORE FILENAME AS NECESSARY
PUSHJ P,GETOCT ;GET OCTAL PROJECT NUMBER
JUMPE T1,CMDERR ;NONE IS ILLEGAL
TRON S,FR.PTH ;ALREADY SEEN A PATH?
CAIE T3,"," ;MUST HAVE BROKEN ON A COMMA
JRST CMDERR ;ELSE ERROR
HRLZM T1,PTHBLK ;STORE IN PATH BLOCK
PUSHJ P,GETOCT ;GET PROGRAM NUMBER
JUMPE T1,CMDERR ;NONE IS ILLEGAL
HRRM T1,PTHBLK ;STORE IN PATH BLOCK
MOVSI W,-LIMLVL ;SETUP AOBJN POINTER TO SFD'S
CMDPT1: CAIE T3,"," ;SFD COMMING?
JRST CMDPT2 ;NO, OR NONE ALLOWED
PUSHJ P,GETSIX ;GET SFD NAME
JUMPE T1,CMDERR ;MUST NOT BE NULL
MOVEM T1,PTHBLK+1(W) ;STORE IN NEXT SLOT IN PATH BLOCK
AOBJN W,CMDPT1 ;LOOP FOR NEXT
CMDPT2: CAIN T3,"]" ;TERMINATE WITH RIGHT BRACKET?
JRST PARSE2 ;YES, GET NEXT ATOM
JRST PARSE1 ;NO, WORRY ABOUT THE CHARACTER
;HERE TO PROCESS THE END OF THE COMMAND LINE ;⊗ CMDEOL
CMDEOL: JSP T2,STOFIL ;STORE FILENAME AS NECESSARY
MOVSI T1,'DSK' ;GET GENERIC DISK
TRNE S,FR.DEV ;DEVICE SEEN?
CAMN T1,DEV ;OR GENERIC DISK?
TLO S,(FL.WLD) ;YES, FLAG IT
MOVSI T1,'EXE' ;DEFAULT EXTENSION IS EXE
TRNN S,FR.EXT ;EXTENSION SEEN?
MOVEM T1,EXT ;NO, USE DEFAULT
MOVE T1,[1,,4] ;DEFAULT DIRECTORY IS [1,4]
TRNN S,FR.PTH ;PATH SEEN?
MOVEM T1,PTHBLK ;NO, STORE DEFAULT
JRST CPOPJ1 ;GIVE SKIP RETURN
;HERE TO PROCESS A SWITCH IN THE COMMAND STRING ;⊗ CMDSWT CMDSW1 CMDSW2 SWTTAB SWTTBL
CMDSWT: JSP T2,STOFIL ;STORE FILENAME AS NECESSARY
PUSHJ P,GETSIX ;GET THE SWITCH
MOVE T2,T1 ;COPY IT TO T2
SETOM W ;SET FULL WORD MASK
CMDSW1: LSH W,-6 ;SHIFT MASK 6
LSH T2,6 ;AND WORD BY SAME AMOUNT
JUMPN T2,CMDSW1 ;UNTIL IT'S NULL
MOVSI T4,-SWTTBL ;GET -VE LENGTH OF SWITCH TABLE
CMDSW2: MOVE T2,SWTTAB(T4) ;GET NEXT ENTRY IN SWITCH TABLE
TDZ T2,W ;MASK TO SAME SIZE AS WHAT USER TYPED
CAME T1,T2 ;MATCH?
AOBJN T4,CMDSW2 ;NO, LOOP FOR NEXT
TLZN T4,-1 ;CLEAR LH. FIND MATCH?
JRST CMDERR ;NO
MOVEI T1,FR.1ST ;GET FIRST SWITCH BIT IN S
LSH T1,(T4) ;SHIFT BY OFFSET INTO SWITCH TABLE
IORI S,(T1) ;SET SWITCH BIT IN S
CAIE T3,":" ;SWITCH HAVE A VALUE?
JRST PARSE1 ;NO, GET NEXT ATOM
CAIL T4,SWTVLL ;CAN THIS SWITCH LEGALLY HAVE A VALUE?
JRST CMDERR ;NO
PUSHJ P,GETOCT ;GET OCTAL VALUE FOR SWITCH
MOVEM T1,SWTVAL(T4) ;STORE VALUE IN TABLE
JRST PARSE1 ;AND GET NEXT ATOM
;TABLE OF LEGAL SWITCHES. NOTE THAT ALL SWITCHES THAT MAY HAVE
;AN OCTAL VALUE MUST OCCUR POSITIONALLY BEFORE THE SWTVLL'TH
;LOCATION IN THE TABLE.
SWTTAB: SIXBIT/START/ ;/START:N
SIXBIT/LOAD/ ;/LOAD
SIXBIT/DUMP/ ;/DUMP
SIXBIT/REBOOT/ ;/REBOOT
SWTTBL==.-SWTTAB
SUBTTL COMMAND INPUT ;⊗ STOFIL GETSIX GETSI1 GETSI2 GETOCT GETOC1
;ROUTINE TO STORE A FILENAME IF REQUIRED.
;CALL:
; T1/FILENAME OR 0
; JSP T2,STOFIL
;RETURN+1 IF NO ERRORS
STOFIL: JUMPE T1,(T2) ;DON'T DO ANYTHING IF NOTHING TO STORE
TROE S,FR.FIL ;ALREADY SEEN A FILENAME?
JRST CMDERR ;YES, ERROR
MOVEM T1,FILNAM ;STORE FILENAME
JRST (T2) ;AND RETURN
;ROUTINE TO READ A SIXBIT NAME FROM THE COMMAND STRING.
;CALL: PUSHJ P,GETSIX
;RETURN+1 ALWAYS
;RETURNS NAME IN T1, BREAK CHARACTER IN T3
;DESTROYS T2
GETSIX: MOVEI T1,0 ;START WITH NULL NAME
MOVE T2,[POINT 6,T1] ;GET BYTE POINTER FOR ATOM
GETSI1: PUSHJ P,GETCHR ;GET NEXT CHARACTER FROM COMMAND
CAIL T3,"A" ;LETTER?
CAILE T3,"Z" ; ??
CAIA ;NO, CHECK DIGITS
JRST GETSI2 ;YES
CAIL T3,"0" ;NUMBER?
CAILE T3,"9" ; ??
POPJ P, ;NO, RETURN
GETSI2: TRC T3,"A"-'A' ;CONVERT ASCII TO SIXBIT
TLNE T2,770000 ;TOO MANY?
IDPB T3,T2 ;NO, STORE IN T1
JRST GETSI1 ;AND LOOP FOR NEXT
;ROUTINE TO RETURN AN OCTAL NUMBER FROM THE COMMAND STRING.
;CALL: PUSHJ P,GETOCT
;RETURN+1 ALWAYS
;RETURNS NUMBER IN T1, BREAK CHARACTER IN T3
GETOCT: MOVEI T1,0 ;START WITH NO NUMBER
GETOC1: PUSHJ P,GETCHR ;GET NEXT CHARACTER FROM COMMAND
CAIL T3,"0" ;NUMBER?
CAILE T3,"7" ; OCTAL THAT IS?
POPJ P, ;NO, RETURN
LSH T1,3 ;MAKE ROOM FOR IT
IORI T1,-"0"(T3) ;INCLUDE IN TOTAL
JRST GETOC1 ;LOOP FOR NEXT
;ROUTINE TO RETURN THE NEXT CHARACTER FROM THE COMMAND STREAM. ;⊗ GETCHR ASKYN CPOPJ1 CPOPJ
;CONVERTS LOWER TO UPPER CASE.
;CALL: PUSHJ P,GETCHR
;RETURN+1 ALWAYS WITH CHARACTER IN T3
GETCHR: ILDB T3,CMDPTR ;READ CHARACTER FROM COMMAND BUFFER
CAIE T3," " ;SPACE?
CAIN T3,.CHTAB ; OR TAB?
MOVEI T3,.CHCRT ;YES, RETURN CR
CAIL T3,"a" ;LOWER CASE?
CAILE T3,"z" ;??
POPJ P, ;NO
SUBI T3,"a"-"A" ;YES, CONVERT TO UPPER
POPJ P, ;AND RETURN
;ROUTINE TO ASK A QUESTION AND GIVE SKIP RETURN IF ANSWER WAS YES.
;CALL:
; T1/ADDRESS OF QUESTION STRING
; PUSHJ P,ASKYN
;RETURN+1 IF ANSWER WAS NO (REALLY NOT YES)
;RETURN+2 IF ANSWER WAS YES
ASKYN: PUSHJ P,REDLIN ;ASK QUESTION, READ ANSWER
PUSHJ P,GETCHR ;GET FIRST CHARACTER
CAIN T3,"Y" ;YES?
CPOPJ1: AOS 0(P) ;YES, GIVE SKIP RETURN
CPOPJ: POPJ P, ;RETURN
;ROUTINE TO PRINT A PROMPT STRING, AND READ A COMMAND LINE INTO ;⊗ REDLIN REDLI1 REDLI2 TPOPJ
;CMDBUF. DOES LOCAL EDITING OF RUBOUT AND ↑U.
;CALL:
; T1/ADDRESS OF PROMPT STRING
; PUSHJ P,REDLIN
;RETURN+1 ALWAYS WITH LINE IN CMDBUF
REDLIN: PUSHJ P,SAVE2 ;SAVE P1-P2
PUSH P,T1 ;SAVE ADDRESS OF PROMPT STRING
REDLI1: MOVE T1,0(P) ;RESTORE ADDRESS FOR SUBSEQUENT TIMES
PUSHJ P,PRMSG ;TYPE PROMPT STRING
MOVE P1,[POINT 7,CMDBUF] ;GET POINTER TO BUFFER
MOVEM P1,CMDPTR ;SAVE FOR CALLER
SETZM CMDBUF ;SET TO CLEAR BUFFER
MOVE T1,[CMDBUF,,CMDBUF+1] ;SETUP FOR BLT
BLT T1,CMDBUF+LINBFL-1 ;ZERO IT ALL
TLZ S,(FL.RUB) ;CLEAR RUBOUT FLAG
MOVEI P2,<LINBFL*5>-5 ;MAX CHARACTERS
REDLI2: PUSHJ P,TYI ;READ A CHARACTER
CAIE T3,.CHCNH ;BACKSPACE?
CAIN T3,.CHDEL ; OR RUBOUT?
JRST REDRUB ;YES
CAIN T3,.CHCNU ;↑U?
JRST REDCNU ;YES
CAIE T3,.CHCRT ;END OF LINE?
SOSL P2 ;IGNORE IF TOO MANY
IDPB T3,P1 ;STASH CHAR
TLZE S,(FL.RUB) ;POST PROCESS RUBOUT
PUSHJ P,PRBSL ;BY PRINTING BACKSLASH
LDB T3,P1 ;GET CHAR BACK
PUSHJ P,ECHO ;AND ECHO CHARACTER
LDB T3,P1 ;ONCE MORE
CAIE T3,.CHCRT ;END-OF LINE?
JRST REDLI2 ;NO, LOOP
TPOPJ: POP P,T1 ;RESTORE T1
POPJ P, ;AND RETURN
;HERE TO PROCESS RUBOUTS ;⊗ REDRUB REDRU1 REDCNU REDCU1
REDRUB: CAIN P2,<LINBFL*5>-5 ;CHECK FOR BEGINNING OF LINE
JRST REDRU1 ;YES
TLON S,(FL.RUB) ;CHECK HERE BEFORE?
PUSHJ P,PRBSL ;NO, TYPE BACKSLASH
LDB T3,P1 ;GET CHAR
PUSHJ P,ECHO ;PRINT IT
IFN FTKI10,<
ADD P1,[POINT 0,0,28] ;BACK UP BYTE PNTR
TLNE P1,(1B0)
SUB P1,[POINT 0,1,0]
>
IFN FTKL10!FTKS10,<
MOVNI T3,1 ;WANT TO BACKUP POINTER BY
EXCH T3,P1 ;BY 1 BYTE POSITION
ADJBP P1,T3 ;DO IT THE EASY WAY
>
AOJA P2,REDLI2 ;GET NEXT CHAR
;HERE TO PROCESS BEGINNING OF LINE ON RUBOUT
REDRU1: TLZE S,(FL.RUB) ;NEED TO TYPE A BACKSLASH?
PUSHJ P,PRBSL ;YES, DO SO
JRST REDCU1 ;JOIN COMMON CODE
;HERE TO PROCESS ↑U
REDCNU: PUSHJ P,ECHO ;ECHO AS UPARROW U
REDCU1: PUSHJ P,PRCRLF ;TYPE CRLF
JRST REDLI1 ;RETYPE PROMPT AND TRY AGAIN
SUBTTL COMMAND OUTPUT ;⊗ PRRBCR PRCRLF PRBSL PRCOMA PRLBKT PRRBKT PRMSG PRMSG1 PRSIX
;ROUTINES TO PRINT SELECTED CHARACTERS.
;
; PRCRLF - PRINT CRLF
; PRBSL - PRINT BACKSLASH
; PRCOMA - PRINT COMMA
; PRLBKT - PRINT LEFT BRACKET
; PRRBKT - PRINT RIGHT BRACKET
; PRRBCR - PRINT RIGHT BRACKET AND CRLF
PRRBCR: PUSHJ P,PRRBKT ;PRINT RIGHT BRACKET AND FALL INTO PRCRLF
PRCRLF: MOVEI T3,.CHCRT ;GET A CR
PUSHJ P,TYO
MOVEI T3,.CHLFD ;GET A LF
PJRST TYO ;TYPE IT AND RETURN
PRBSL: SKIPA T3,["\"] ;GET A BACKSLASH
PRCOMA: MOVEI T3,"," ;GET A COMMA
PJRST TYO ;TYPE IT AND RETURN
PRLBKT: SKIPA T3,["["] ;GET A LEFT BRACKET
PRRBKT: MOVEI T3,"]" ;GET A RIGHT BRACKET
PJRST TYO ;TYPE IT AND RETURN
;ROUTINE TO PRINT AN ASCIZ MESSAGE ON THE CTY.
;CALL:
; T1/ADDRESS OF ASCIZ STRING
; PUSHJ P,PRMSG
;RETURN+1 ALWAYS
;DESTROYS T1,T3
PRMSG: HRLI T1,(POINT 7,) ;FORM 7 BIT BYTE POINTER
PRMSG1: ILDB T3,T1 ;GET NEXT CHARACTER
JUMPE T3,CPOPJ ;RETURN ON NULL
PUSHJ P,TYO ;TYPE CHARACTER
JRST PRMSG1 ;LOOP FOR NEXT
;ROUTINE TO PRINT A SIXBIT WORD ON THE CTY.
;CALL:
; T1/SIXBIT WORD
; PUSHJ P,PRSIX
;RETURN+1 ALWAYS
;DESTROYS T1,T2,T3
PRSIX: LSHC T1,-↑D36 ;MOVE WORD TO T2, CLEAR T1
LSHC T1,6 ;MOVE NEXT BYTE TO T1
MOVEI T3,"A"-'A'(T1) ;CONVERT TO ASCII AND COPY TO T3
PUSHJ P,TYO ;PUT IT OUT
SKIPE T1,T2 ;MOVE REMAINDER BACK TO T1, SKIP IF DONE
JRST PRSIX ;LOOP FOR REST
POPJ P, ;RETURN
;ROUTINE TO PRINT AN OCTAL NUMBER ON THE CTY. ;⊗ PROCT PRHWD PRHWD1 PRHWD2 ECHO
;CALL:
; T1/NUMBER TO PRINT
; PUSHJ P,PROCT
;RETURN+1 ALWAYS
;DESTROYS T1,T2,T3
PROCT: IDIVI T1,↑D8 ;DIVIDE BY RADIX, REMAINDER IN T2
HRLM T2,0(P) ;STORE ON STACK
SKIPE T1 ;DONE?
PUSHJ P,PROCT ;NO, LOOP
HLRZ T3,0(P) ;GET DIGIT FROM STACK
ADDI T3,"0" ;CONVERT TO ASCII
PJRST TYO ;OUTPUT IT AND RETURN TO CALLER
;ROUTINE TO PRINT A WORD AS TWO 6 DIGIT OCTAL NUMBERS SEPARATED
;BY TWO COMMAS.
;CALL:
; T4/WORD
; PUSHJ P,PRHWD
;RETURN+1 ALWAYS
PRHWD: PUSHJ P,PRHWD1 ;PRINT LEFT HALF
MOVEI T1,[ASCIZ/,,/] ;FOLLOWED BY
PUSHJ P,PRMSG ; TWO COMMAS
PRHWD1: MOVEI T1,6 ;LOOP COUNT IS 6
PRHWD2: MOVE T3,T4 ;MOVE WORD TO T3
LSHC T3,-↑D33 ;KEEP 1 DIGIT, CLEAR REST OF T3
ADDI T3,"0" ;CONVERT TO ASCII
PUSHJ P,TYO ;PUT IT OUT
SOJG T1,PRHWD2 ;LOOP FOR ALL
POPJ P, ;RETURN
;ROUTINE TO PRINT ONE CHARACTER IN (POSSIBLY) UP-ARRROW FORMAT.
;CALL:
; T3/CHARACTER TO ECHO
; PUSHJ P,ECHO
;RETURN+1 ALWAYS
;DESTROYS T3
ECHO: CAIE T3,.CHTAB ;TAB?
CAIL T3," " ;NO, CONTROL CHARACTER?
PJRST TYO ;NO, JUST PRINT IT
CAIN T3,.CHCRT ;END-OF-LINE?
PJRST PRCRLF ;YES, ECHO CRLF
PUSH P,T3 ;SAVE CHAR
MOVEI T3,"↑" ;PRINT CTRL CHAR
PUSHJ P,TYO ;...
POP P,T3 ;RESTORE CHARACTER
ADDI T3,"A"-1 ;CONVERT TO PRINTING CHARACTER
PJRST TYO ;PRINT IT AND RETURN
;ROUTINE TO PRINT THE CURRENT FILESPEC FROM THE DATA BASE. ;⊗ PRFILE PRFIL1
;CALL: PUSHJ P,PRFILE
;RETURN+1 ALWAYS
;DESTROYS T1-T4
PRFILE: MOVE T1,DEV ;GET DEVICE NAME
PUSHJ P,PRSIX ;PRINT IT
MOVEI T3,":" ;GET A COLON
PUSHJ P,TYO ;PRINT IT
MOVE T1,FILNAM ;GET THE FILENAME
PUSHJ P,PRSIX ;PRINT IT
MOVEI T3,"." ;GET A DOT
PUSHJ P,TYO ;PRINT IT
HLLZ T1,EXT ;GET EXTENSION
PUSHJ P,PRSIX ;PRINT IT
PUSHJ P,PRLBKT ;PRINT LEFT BRACKET
HLRZ T1,PTHBLK ;GET PROJECT NUMBER
PUSHJ P,PROCT ;PRINT IT
PUSHJ P,PRCOMA ;PRINT COMMA
HRRZ T1,PTHBLK ;GET PROGRAMMER NUMBER
PUSHJ P,PROCT ;PRINT IT
MOVEI T4,1 ;OFFSET INTO PTHBLK OF FIRST SFD
PRFIL1: SKIPN T1,PTHBLK(T4) ;NEXT SFD NON-NULL?
PJRST PRRBKT ;NO, PRINT RIGHT BRACKET AND RETURN
PUSHJ P,PRCOMA ;PRINT COMMA
PUSHJ P,PRSIX ;PRINT SFD NAME
AOJA T4,PRFIL1 ;LOOP FOR NEXT SFD
SUBTTL LOWEST LEVEL CTY INPUT/OUTPUT ROUTINES ;⊗ TYO DODTE
;ROUTINE TO TYPE ONE CHARACTER ON THE CTY.
;CALL:
; T3/CHARACTER TO TYPE
; PUSHJ P,TYO
;RETURN+1 ALWAYS
;DESTROYS T3.
TYO:
IFN FTKL10,<
MOVSI T3,DT.MTO(T3) ;GET CHAR IN LOW ORDER 8 BITS, COMMAND IN NEXT FOUR
HRRI T3,DTEMTD ;PUT WORD OFFSET IN RH
DODTE: SETZM EPT(T3) ;CLEAR DONE FLAG
HLRZM T3,EPT+DTECMD ;PUT INTO COMMAND LOCATION
CONO DTE0,TO11DB ;RING DOORBELL
SKIPN EPT(T3) ;WAIT TILL MONITOR OUTPUT DONE
JRST .-1 ;LOOP
POPJ P,0 ;DONE.
>;END IFN FTKL10
IFN FTKI10,<
DATAO TTY,T3 ;SEND OUT CHAR
CONSZ TTY,IT.BSY ;WAIT FOR IDLE
JRST .-1 ; ..
POPJ P,0 ;DONE.
>;END IFN FTKI10
IFN FTKS10,<
SKIPE .VPAG0+CTYOWD ;CAN WE SEND NEXT CHAR?
JRST .-1 ;NOT YET
IORI T3,CTYOVL ;SIGNAL VALID
MOVEM T3,.VPAG0+CTYOWD ;PUT IT UP FOR THE 8080 TO FIND IT
WRAPR SP.SSF!SP.IFE ;WAKE THE 8080
POPJ P,0 ;DONE
>;END IFN FTKS10
;ROUTINE TO READ ONE CHARACTER FROM THE CTY. ;⊗ TYI BRKTAB
;CALL: PUSHJ P,TYI
;RETURN+1 ALWAYS WITH CHARACTER IN T3
;DESTROYS T1
TYI:
IFN FTKL10,<
SKIPN EPT+DTEMTI ;INPUT READY?
>
IFN FTKI10,<
CONSO TTY,IT.DON ;INPUT READY?
>
IFN FTKS10,<
SKIPN .VPAG0+CTYIWD ;INPUT READY?
>
JRST .-1 ;NO, LOOP
IFN FTKL10,<
MOVE T3,EPT+DTEF11 ;GET CHARACTER
SETZM EPT+DTEMTI ;FLAG WE GOT IT
>;END IFN FTKL10
IFN FTKI10,<
DATAI TTY,T3 ;GET THE CHARACTER
>;END IFN FTKI10
IFN FTKS10,<
MOVEI T3,0 ;SET TO GET CHAR AND CLEAR WORD
EXCH T3,.VPAG0+CTYIWD ;GET CHARACTER AND CLEAR
>;END IFN FTKS10
ANDI T3,177 ;KEEP ONLY 7 BITS
JUMPE T3,TYI ;IGNORE NULLS
MOVEI T1,1 ;GET A BIT TO SHIFT
LSH T1,(T3) ;SHIFT BY VALUE OF CHARACTER
TDNE T1,BRKTAB ;BREAK CHARACTER?
MOVEI T3,.CHCRT ;YES, CONVERT TO CR
POPJ P, ;RETURN
BRKTAB: 1←.CHBEL!1←.CHTAB!1←.CHLFD!1←.CHVTB!1←.CHFFD!1←.CHCNZ!1←.CHESC!1←" "
SUBTTL DISK SUPPORT SUBROUTINES ;⊗ REDREG DRVTYP DRVTY1
IFE FTKS10,<
;ROUTINE TO READ A MASSBUS REGISTER AND RETURN THE VALUE.
;CALL WITH:
; T1/DATAO WORD
; PUSHJ P,REDREG
;RETURN+1 ALWAYS WITH FULL 36 BIT DATA IN T1
REDREG: XCT DODATO ;TELL THE DEVICE WHICH REGISTER
STALL ;WAIT AWHILE
XCT DODATI ;READ THE DATA
POPJ P, ;RETURN
>;END IFE FTKS10
;ROUTINE TO READ AND CHECK THE DRIVE TYPE REGISTER FOR A DEVICE AGAINST
;THOSE DRIVE TYPES THAT WE KNOW ABOUT.
;CALL:
; T1/DATAO WORD TO READ DRIVE TYPE REGISTER
; PUSHJ P,DRVTYP
;RETURN+1 IF NO MATCH
;RETURN+2 IF MATCH WITH DRVBPC, DRVBPT SETUP
DRVTYP:
IFE FTKS10,<
PUSHJ P,REDREG ;READ THE REGISTER
>
IFN FTKS10,<
TRNN T1,SI.DSK ;THIS A DISK UNIT?
POPJ P, ;NO
>
ANDI T1,777 ;KEEP ONLY 9 BITS
MOVSI T2,-DRTTBL ;GET AOBJN POINTER TO DRIVE TYPE TABLE
DRVTY1: CAME T1,DRTTAB(T2) ;MATCH WITH THIS ONE?
AOBJN T2,DRVTY1 ;NO, LOOP
JUMPGE T2,CPOPJ ;FAIL IF NO MATCH
MOVE T1,BPCTAB(T2) ;GET BLOCKS/CYLINDER
MOVE T2,BPTTAB(T2) ; AND BLOCKS/TRACK
DMOVEM T1,DRVBPC ;STORE VALUES
JRST CPOPJ1 ;GIVE SKIP RETURN
;TABLES DEFINING THE DRIVE TYPES OF THE DRIVES WE KNOW ABOUT AND ;⊗ DRTTAB DRTTBL BPCTAB BPTTAB
;THE CORRESPONDING VALUES OF BLOCKS/CYLINDER AND BLOCKS/TRACK FOR
;EACH DRIVE. THESE ARE PARALLEL TABLES AND THUS ARE ORDER SENSITIVE.
;
;TABLE GIVING THE DRIVE TYPES THAT WE KNOW ABOUT.
DRTTAB: EXP 20 ;RP04
EXP 22 ;RP06
EXP 24 ;RM03
EXP 42 ;RP07
DRTTBL==.-DRTTAB
;TABLE GIVING THE NUMBER OF BLOCKS/CYLINDER FOR EACH DRIVE.
BPCTAB: DEC 380 ;RP04
DEC 380 ;RP06
DEC 150 ;RM03
DEC 1376 ;RP07
;TABLE GIVING THE NUMBER OF BLOCKS/TRACK FOR EACH DRIVE.
BPTTAB: DEC 20 ;RP04
DEC 20 ;RP04
DEC 30 ;RM03
DEC 43 ;RP07
SUBTTL BYTE POINTERS INTO DATA STRUCTURES ;⊗ DESRBU DENRBU DESRBA DENRBA DEYRBU DEYRBA
DESRBU==↑D4 ;SIZE OF UNIT NUMBER FIELD IN RIBXRA
DENRBU==↑D12 ;BIT POSITION OF UNIT NUMBER FIELD IN RIBXRA
DESRBA==↑D23 ;SIZE OF CLUSTER ADDRESS FIELD IN RIBXRA
DENRBA==↑D35 ;BIT POSITION OF CLUSTER ADDRESS FIELD IN RIBXRA
DEYRBU: POINT DESRBU,RIB+RIBXRA,DENRBU
;UNIT ON WHICH NEXT EXTENDED RIB EXISTS
DEYRBA: POINT DESRBA,RIB+RIBXRA,DENRBA
;CLUSTER ADDRESS ON UNIT ON WHICH NEXT EXTENDED
;RIB EXISTS
SUBTTL TABLES DRIVING DEVICE DEPENDENT I/O ;⊗ DVCTAB DVCTBL IOTTAB DODATO DODATI DOCONI DOCONO DOCNSO IOTTBL
;TABLE GIVING DEVICE CODES OF CONTROLLERS THAT WE CAN TALK TO.
;TABLE IS ORDERED (HOPEFULLY) SO THAT WE WILL FIND THE FILE IN THE
;LEAST DISK ACCESSES.
;FORMAT IS:
; XWD <OFFSET INTO TYPE TABLES>,<DEVICE CODE>←-2
DEFINE DCODE(CODE,OFS,FTS),<
IFN FTS,<
XWD OFS,CODE←-2
>
>
DVCTAB: DCODE (540,R20OFS,FTKL10) ;RH20 0 ON KL
DCODE (544,R20OFS,FTKL10) ;RH20 1 ON KL
DCODE (550,R20OFS,FTKL10) ;RH20 2 ON KL
DCODE (554,R20OFS,FTKL10) ;RH20 3 ON KL
DCODE (270,R10OFS,FTKI10!FTKL10) ;RH10 0 ON KI OR KL
DCODE (274,R10OFS,FTKI10!FTKL10) ;RH10 1 ON KI OR KL
DCODE (560,R20OFS,FTKL10) ;RH20 4 ON KL
DCODE (564,R20OFS,FTKL10) ;RH20 5 ON KL
DCODE (570,R20OFS,FTKL10) ;RH20 6 ON KL
DCODE (574,R20OFS,FTKL10) ;RH20 7 ON KL
DCODE (360,R10OFS,FTKI10!FTKL10) ;RH10 2 ON KI OR KL
DCODE (364,R10OFS,FTKI10!FTKL10) ;RH10 3 ON KI OR KL
DCODE (<1←2>,R11OFS,FTKS10) ;RH11 UBA 1 ON KS
DVCTBL==.-DVCTAB
;TABLE OF I/O INSTRUCTIONS. DEVICE CODES FILLED IN BEFORE USE.
IOTTAB:
IFN FTKI10!FTKL10,<
DODATO: DATAO 0,T1
DODATI: DATAI 0,T1
DOCONI: CONI 0,T1
DOCONO: CONO 0,(T1)
DOCNSO: CONSO 0,(T1)
>;END IFN FTKI10!FTKL10
IOTTBL==.-IOTTAB
;THE FOLLOWING TABLES GIVE THE DISPATCH ADDRESSES FOR THE CONTROLLER ;⊗ OFS REDTAB WRTTAB
;DEPENDENT READ AND WRITE ROUTINES. ALL ARE CALLED WITH THE FOLLOWING
;AC'S SETUP:
;
; J = INDEX INTO DEVICE CODE TABLE
; U = PHYSICAL UNIT NUMBER
; W = OFFSET INTO TABLES BELOW
; R = PHYSICAL MEMORY ADDRESS OF START OF TRANSFER
; F = BLOCK ON UNIT OF FIRST BLOCK TO TRANSFER
; M = NUMBER OF CONTIGUOUS BLOCKS TO TRANSFER
;
;ALL CONTROLLER DEPENDENT ROUTINES MUST PRESERVE F AND R WITH
;A CALL TO SAVFR.
;
;**** THE RH10 AND RH20 ENTRIES IN THE FOLLOWING TABLES MUST BE
;**** THE FIRST AND SECOND ENTRIES IN THE TABLES AND MUST REMAIN
;**** IN THE SAME RELATIVE ORDER.
DEFINE DADDR(ADDR,OFS,FTS),<
IFN FTS,<
OFS==.-REDTAB
EXP ADDR
>
>
;TABLE OF ADDRESSES OF CONTROLLER READ ROUTINES INDEXED BY CONTROLLER
;TYPE.
REDTAB: DADDR (R12RED,R10OFS,FTKI10!FTKL10)
DADDR (R12RED,R20OFS,FTKL10)
DADDR (R11RED,R11OFS,FTKS10)
DEFINE DADDR (ADDR,FTS),<
IFN FTS,<
EXP ADDR
>
>
;TABLE OF ADDRESSES OF CONTROLLER WRITE ROUTINES INDEXED BY CONTROLLER
;TYPE.
WRTTAB: DADDR (R12WRT,FTKI10!FTKL10)
DADDR (R12WRT,FTKL10)
DADDR (R11WRT,FTKS10)
IFN FTKL10!FTKI10,< ;⊗ R12WRT R12RED R12XFR R10XFR R12XF1
SUBTTL RH10/RH20 DEVICE DEPENDENT ROUTINES
;ROUTINES TO READ FROM/WRITE TO A DRIVE ON AN RH10/RH20. CALL WITH THE
;STANDARD AC'S SETUP. TRANSLATES THE DEVICE INDEPENDENT TRANSFER
;REQUEST INTO AS MANY TRANSFERS AS NECESSARY TO MAKE THE RH10/RH20 HAPPY.
;CALL: PUSHJ P,R12RED -OR- PUSHJ P,R12WRT
;RETURN+1 IF I/O ERRORS
;RETURN+2 IF TRANSFER WAS SUCCESSFUL
R12WRT: TLOA S,(FL.IO) ;SET FLAG FOR OUTPUT
R12RED: TLZ S,(FL.IO) ;CLEAR FLAG FOR INPUT
PUSHJ P,SAVFR ;SAVE F AND R
PUSHJ P,R12INI ;INITIALIZE THE RH10/RH20
POPJ P, ;FAILED
R12XFR: JUMPLE M,CPOPJ1 ;DONE WHEN TRANSFERED ALL BLOCKS
TLNE S,(FL.IO) ;WRITING?
CAILE F,LB2HOM+LBOBAT ;YES, ON HOM OR BAT BLOCKS?
CAIA ;NO
HALT . ;YES, DON'T MAKE THINGS WORSE
PUSHJ P,R12CLR ;MAKE SURE THE RH10/RH20 IS CLEARED
PUSHJ P,R12SET ;MAKE IOWDS, TELL DRIVE WHERE TO START
IFN FTKL10,<
JUMPE W,R10XFR ;DIFFERENT IF RH10
MOVSI T1,<(DO.2ST)>(U) ;TALK TO STCR AND SPECIFIED DRIVE
DPB T4,[POINT 10,T1,29] ;STORE -VE BLOCKCOUNT
JRST R12XF1 ;JOIN COMMON CODE
>
R10XFR: MOVSI T1,<(DO.1CR)>(U) ;TALK TO COMMAND REGISTER AND SPECIFIED DRIVE
HRRI T1,<BOOTWD←6> ;SET INITIAL CONTROL WORD ADDRESS
R12XF1: TLNN S,(FL.IO) ;DOING OUTPUT?
TROA T1,DO.XRD ;NO, SET READ FUNCTION CODE
TRO T1,DO.XWT ;YES, SET WRITE FUNCTION CODE
XCT DODATO ;START THE TRANSFER
PUSHJ P,R12WAT ;WAIT FOR IT TO COMPLETE
PUSHJ P,R12CHK ;CHECK FOR ERRORS
POPJ P, ;GIVE NON-SKIP RETURN IF ERRORS OR TIMED OUT
JRST R12XFR ;DO MORE IF ANY BLOCKS LEFT
;ROUTINE TO SETUP THE CHANNEL COMMAND LIST FOR THIS TRANSFER AND ;⊗ R12SET R12SE1 R12SE2 R12SE3 R12SE4 R12SE5 R12SE6
;TELL THE DRIVE WHERE TO START THE TRANSFER. CALL WITH THE STANDARD
;AC'S SETUP.
;CALL: PUSHJ P,R12SET
;RETURN+1 ALWAYS
;RETURNS WITH M, R, AND F UPDATED TO REFLECT THIS TRANSFER AND
; T4/NEGATIVE BLOCKCOUNT FOR THIS TRANSFER
R12SET: MOVEI T4,0 ;INITIALIZE BLOCK COUNT TO 0
IFN FTKL10,<
JUMPE W,R12SE2 ;NO LOGOUT AREA FOR RH10'S
HRRZ T1,DVCTAB(J) ;GET DEVICE CODE FOR THIS DEVICE
LSH T1,2 ;TIMES 2
SUBI T1,540 ;COMPUTE OFFSET IN EPT OF LOGOUT AREA
MOVE T2,EPTADR ;GET PHYSICAL ADDRESS OF THE EPT
ADDI T2,R2IOWD-EPT ;ADD OFFSET TO FIRST IOWD
TLO T2,(RH2JMP) ;MAKE IT A JUMP WORD
MOVEM T2,EPT(T1) ;STORE JUMP WORD IN LOGOUT AREA
MOVSI T1,-<R2IOWL-1> ;MAKE AOBJN POINTER TO IOWD LIST
R12SE1: JUMPLE M,R12SE5 ;STOP WHEN DONE ENTIRE TRANSFER
>
R12SE2: MOVEI T2,(M) ;ASSUME LESS THAN MAX
CAMLE M,[R1BCNT
R2BCNT](W) ;ARE WE CORRECT?
MOVE T2,[R1BCNT
R2BCNT](W) ;NO, MAKE IT THE MAX POSSIBLE IN 1 IOWD
SUBI M,(T2) ;DECREMENT BLOCKS REMAINING
SUBI T4,(T2) ;AND BLOCKS DONE
LSH T2,B2WLSH ;CONVERT TO WORDS
IFN FTKL10,<
JUMPE W,R12SE3 ;GO IF RH10
LSH T2,↑D18+4 ;POSITION IN IOWD
TLO T2,(RH2TRA) ;MAKE THE OPCODE A TRANSFER
IOR T2,R ;STORE PHYSICAL ADDRESS
MOVEM T2,R2IOWD(T1) ;STORE IN CHANNEL COMMAND LIST
ADDI R,R2WCNT ;INCREMENT CORE ADDRESS FOR NEXT TIME
JRST R12SE4 ;JOIN COMMON CODE
>
R12SE3: MOVNS T2 ;RH10'S WANT A NEGATIVE WORDCOUNT
LSH T2,↑D18 ;MOVE TO LH
XCT DOCONI ;GET CONI FOR DRIVE
TLNE T1,(CI.122) ;SKIP IF 18 BIT DF10
LSH T2,4 ;DF10C'S ONLY HAVE 14 BITS OF WORDCOUNT
IOR T2,R ;STORE PHYSICAL ADDRESS
SUBI T2,1 ;AND ADDRESS-1
MOVEM T2,.VPAG0+BOOTWD ;STORE IOWD IN LOW CORE
SETZM .VPAG0+BOOTWD+1 ;INSURE IOWD TERMINATION
ADDI R,R1WCNT ;INCREMENT CORE ADDRESS FOR NEXT TIME
IFN FTKL10,<
JRST R12SE6 ;DO ONLY ONE IOWD FOR AN RH10
R12SE4: AOBJN T1,R12SE1 ;DO AS MANY AS POSSIBLE
R12SE5: SETZM R2IOWD(T1) ;STORE HALT IOWD TO TERMINATE LIST
>
R12SE6: MOVE T1,F ;COPY BLOCK ADDRESS
SUB F,T4 ;UPDATE FOR AMOUNT OF THIS TRANSFER
IDIV T1,DRVBPC ;T1=CYLINDER, T2=REMAINDER
HRLI T1,<(DO.XDC)>(U) ;STORE IN DESIRED CYLINDER REGISTER
XCT DODATO ;TELL THE DRIVE
IDIV T2,DRVBPT ;T2=TRACK, T3=SECTOR
DPB T2,[POINT 8,T3,27] ;POSITION CORRECTLY
MOVSI T1,<(DO.XDS)>(U) ;TALK TO THE BLOCK ADDRESS REGISTER
HRRI T1,(T3) ;STORE ADDRESS
XCT DODATO ;TELL THE DRIVE
POPJ P, ;RETURN
;ROUTINE TO INITIALIZE THE RH10/RH20 FOR A TRANSFER. ;⊗ R12INI R12CHK
;CALL: PUSHJ P,R12INI
;RETURN+1 IF INITIALIZATION FAILED
;RETURN+2 IF SUCCESSFUL
R12INI: XCT DOCONI ;GET CONI IN T1
JUMPE T1,CPOPJ ;NO BITS MEANS IT DOESN'T EXIST
PUSHJ P,R12CLR ;BLAST THE RH10/RH20 INTO A KNOWN STATE
MOVSI T1,<(DO.XDT)>(U) ;NEED DRIVE TYPE REGISTER FOR THIS DRIVE
PUSHJ P,DRVTYP ;READ AND CHECK IT
POPJ P, ;NO MATCH
MOVSI T1,<(DO.XCR)>(U) ;POINT TO DRIVE CONTROL REGISTER
HRRI T1,DO.XCL ;FUNCTION IS DRIVE CLEAR
XCT DODATO ;CLEAR THE DRIVE
HRRI T1,DO.XRP ;FOLLOWED BY A READIN
XCT DODATO ; PRESET
MOVSI T1,<(DO.XSR)>(U) ;SETUP TO READ STATUS REGISTER
PUSHJ P,REDREG ;DO SO
ANDI T1,DI.XSM ;MASK, IGNORING WRITE LOCK, PGM
CAIE T1,DI.XSB ;IS IT OK?
POPJ P, ;NO
JRST CPOPJ1 ;GIVE SKIP RETURN
;ROUTINE TO CHECK THE RH10/RH20 FOR ERRORS IN THE LAST TRANSFER.
;CALL: PUSHJ P,R12CHK
;RETURN+1 IF ERRORS DETECTED
;RETURN+2 IF NO ERRORS
R12CHK: MOVSI T1,<(DO.XSR)>(U) ;SET TO READ STATUS REGISTER
PUSHJ P,REDREG ;DO SO
TRNE T1,DI.XCE ;COMPOSITE ERROR?
POPJ P, ;YES, GIVE ERROR RETURN
MOVE T1,[CI.1ER
CI.2ER](W) ;GET CONI ERROR BITS FOR CONTROLLER
XCT DOCNSO ;ANY SET?
JRST CPOPJ1 ;NO, GIVE SKIP RETURN
POPJ P, ;YES
;ROUTINE TO WAIT FOR THE RH10/RH20 TO FINISH A TRANSFER. ;⊗ R12WAT R12CLR
;CALL: PUSHJ P,R12WAT
;RETURN+1 IF SUCCESSFUL
;RETURN+2 IF TIMED OUT
R12WAT: MOVSI T2,10 ;LOOP COUNT = ABOUT 7 SECONDS
MOVE T1,[CI.1RA!CI.XDN
CI.2RA!CI.XDN](W) ;WAIT FOR DONE OR RAE TO COME UP
XCT DOCNSO ;IN THE CONI
SOJG T2,.-1 ;HASN'T YET, WAIT FOR IT
JUMPLE T2,CPOPJ1 ;GIVE SKIP RETURN IF TIMED OUT
POPJ P, ;RETURN
;ROUTINE TO FORCE THE RH10/RH20 INTO A KNOWN STATE FOR A TRANSFER.
;CALL: PUSHJ P,R12CLR
;RETURN+1 ALWAYS
R12CLR: MOVEI T1,CO.XMI ;DO A
XCT DOCONO ; MASSBUS INIT
IFN FTKL10,<
MOVEI T1,CO.XSX ;THEN A
XCT DOCONO ; STOP TRANSFER
MOVEI T1,CO.XDN ;THEN A
XCT DOCONO ; CLEAR DONE
MOVEI T1,CO.2ME ;AND FINALLY A
XCT DOCONO ; MASSBUS ENABLE
>
POPJ P,
>;END IFN FTKL10!FTKI10
IFN FTKS10,< ;⊗ R11WRT R11RED R11XFR R11XF1
SUBTTL RH11 DEVICE DEPENDENT ROUTINES
;ROUTINES TO READ FROM/WRITE TO A DRIVE ON AN RH11. CALL WITH THE
;STANDARD AC'S SETUP. TRANSLATES DEVICE INDEPENDENT TRANSFER REQUEST
;TO AS MANY TRANSFERS AS NECESSARY TO MAKE THE RH11 HAPPY.
;CALL: PUSHJ P,R11RED -OR- PUSHJ P,R11WRT
;RETURN+1 IF I/O ERRORS
;RETURN+2 IF TRANSFER WAS SUCCESSFUL
R11WRT: TLOA S,(FL.IO) ;SET FLAG FOR OUTPUT
R11RED: TLZ S,(FL.IO) ;CLEAR FLAG FOR INPUT
PUSHJ P,SAVFR ;SAVE F AND R
HRLZ T4,DVCTAB(J) ;SET T4=UBA,,0
PUSHJ P,R11INI ;INITIALIZE THE RH11
POPJ P, ;FAILED
R11XFR: JUMPLE M,CPOPJ1 ;DONE WHEN TRANSFERED ALL BLOCKS
TLNE S,(FL.IO) ;WRITING?
CAILE F,LB2HOM+LBOBAT ;YES, ON HOM OR BAT BLOCKS?
CAIA ;NO
HALT . ;YES, DON'T MAKE THINGS WORSE
PUSHJ P,R11CLR ;CLEAR THE RH11
WRIO U,SO.CS2(T4) ;SELECT DRIVE
PUSH P,T4 ;SAVE T4
PUSHJ P,R11SET ;SET UBA MAP SLOTS, DRIVE LBN
POP P,T4 ;RESTORE T4
MOVEI T1,SO.WRT ;ASSUME WRITING
TLNN S,(FL.IO) ;ARE WE CORRECT?
MOVEI T1,SO.RED ;NO, SET READING
WRIO T1,SO.CS1(T4) ;START THE TRANSFER
MOVSI T2,2 ;LOOP COUNT
R11XF1: RDIO T1,SO.CS1(T4) ;READ STATUS REGISTER
TRNN T1,SI.RDY ;READY COME UP?
SOJG T2,R11XF1 ;NO, LOOP
JUMPLE T2,CPOPJ ;ERROR RETURN IF TIMED OUT
TRNE T1,SI.S1E ;ERRORS?
POPJ P, ;YES
JRST R11XFR ;DO MORE IF ANY BLOCKS LEFT
;ROUTINE TO SETUP THE UBA MAPPING REGISTERS, AND THE DRIVE REGISTERS ;⊗ R11SET R11SE1
;FOR THIS TRANSFER. CALL WITH THE STANDARD AC'S SETUP.
;CALL:
; T4/UBA,,0
; PUSHJ P,R11SET
;RETURN+1 ALWAYS
;RETURNS WITH M, R, AND F UPDATED TO REFLECT THIS TRANSFER.
;DESTROYS T4
R11SET: MOVEI T1,(R) ;GET ADDRESS OF FIRST WORD TO TRANSFER
ANDI T1,PAGSIZ-1 ;ISOLATE OFFSET OF FIRST WORD IN PAGE
LSH T1,2 ;MAKE IT A BYTE OFFSET
WRIO T1,SO.BA(T4) ;SET THE BUS ADDRESS REGISTER
MOVE T1,F ;COPY LBN OF FIRST BLOCK TO TRANSFER
IDIV T1,DRVBPC ;T1=CYLINDER, T2=BLOCK IN CYLINDER
WRIO T1,SO.DC(T4) ;SET DESIRED CYLINDER REGISTER
IDIV T2,DRVBPT ;T2=TRACK, T3=BLOCK IN TRACK
DPB T2,[POINT 8,T3,27] ;POSITION TRACK NUMBER
WRIO T3,SO.DA(T4) ;TELL DRIVE
MOVEI T1,(M) ;ASSUME WE CAN DO ALL OF TRANSFER
CAILE T1,RSBCNT ;LARGER THAN MAX?
MOVEI T1,RSBCNT ;YES, USE MAX
SUBI M,(T1) ;ADJUST M FOR NEXT TIME
ADDI F,(T1) ;ADVANCE TO FIRST BLOCK OF NEXT TRANSFER
MOVE T2,R ;COPY CORE ADDRESS OF FIRST WORD
LSH T1,B2WLSH ;COMPUTE WORD COUNT
ADD R,T1 ;ADVANCE CORE ADDRESS FOR NEXT TIME
LSH T1,1 ;COMPUTE PDP11 WORD COUNT
MOVNS T1 ;MAKE IT NEGATIVE
WRIO T1,SO.WC(T4) ;SET WORD COUNT REGISTER
LSH T2,W2PLSH ;COMPUTE PAGE NUMBER OF 1ST PAGE
MOVE T1,R ;GET ADDRESS OF FIRST WORD OF NEXT TRANSFER
SUBI T1,1 ;MAKE IT LAST ADDRESS OF THIS TRANSFER
LSH T1,W2PLSH ;COMPUTE PAGE NUMBER
SUBI T1,-1(T2) ;COMPUTE NUMBER OF PAGES TO MAP
MOVNS T1 ;MAKE IT NEGATIVE
HRL T2,T1 ;AND MAKE AN AOBJN POINTER
TRO T2,SO.VFT ;SET VALID AND FAST TRANSFER
R11SE1: WRIO T2,SO.UPR(T4) ;MAP ONE PAGE
ADDI T4,1 ;INCREMENT UBA MAP ADDRESS
AOBJN T2,R11SE1 ;LOOP FOR ALL
POPJ P, ;RETURN
;ROUTINE TO INITIALIZE THE RH11 FOR A TRANSFER. ;⊗ R11INI R11CLR
;CALL:
; T4/UBA,,0
; PUSHJ P,R11INI
;RETURN+1 IF INITIALIZATION FAILED
;RETURN+2 IF SUCCESSFUL
R11INI: RDIO T1,SO.USR(T4) ;READ UBA STATUS REGISTER
TRNE T1,SI.UER ;ANY ERRORS?
POPJ P, ;YES, ERROR
PUSHJ P,R11CLR ;CLEAR THE RH11
WRIO U,SO.CS2(T4) ;SELECT DRIVE
RDIO T1,SI.DT(T4) ;READ DRIVE TYPE REGISTER
PUSHJ P,DRVTYP ;CHECK IT
POPJ P, ;FAILED
MOVEI T1,SO.DCL ;GET DRIVE CLEAR FUNCTION
WRIO T1,SO.CS1(T4) ;DO IT
MOVEI T1,SO.RIP ;GET READIN PRESET FUNCTION
WRIO T1,SO.CS1(T4) ;DO IT
RDIO T1,SO.DS(T4) ;READ DRIVE STATUS REGISTER
ANDI T1,SO.DSM ;MASK, IGNORING WRITE LOCK, PGM
CAIE T1,SO.DSB ;IS IT OK?
POPJ P, ;NO
JRST CPOPJ1 ;GIVE SKIP RETURN
;ROUTINE TO FORCE THE RH11 INTO A KNOWN STATE.
;CALL:
; T4/UBA,,0
; PUSHJ P,R11CLR
;RETURN+1 ALWAYS
R11CLR: MOVEI T1,SO.UBI ;UBA INIT
WRIO T1,SO.USR(T4) ;CLEAR THE UBA/DRIVES
POPJ P, ;RETURN
>;END IFN FTKS10
$DEPHASE ;⊗ BOOLEN BOOPGS BOOEND
BOOLEN==.-BOOTVA ;LENGTH OF BOOT
BOOPGS==<BOOLEN+PAGSIZ-1>/PAGSIZ ;LENGTH IN PAGES
DEFINE PRTLEN(FPAGE,LPAGE),<
PRINTX [BOOT will be loaded into physical pages FPAGE through LPAGE]
>
IF2 <
IFG <FTPAGE+BOOPGS-1000>,<
PRINTX ?BOOT assembly crosses above 256K boundary
>
IFLE <FTPAGE+BOOPGS-1000>,<
PRTLEN (\FTPAGE,\<FTPAGE+BOOPGS-1>)
>>
BOOEND: END BOOT